home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / utility / fdate.zip / FDATE.TXT < prev    next >
Text File  |  1997-05-22  |  153KB  |  3,886 lines

  1. FDATE                     Version 9.6a              1997 April 22
  2. ======================================================================
  3. "Everything you'd ever want to do with dates in batch files"
  4. ======================================================================
  5.  
  6. AUTHOR:     Stephen Ferg             
  7.             608 N. Harrison Street
  8.             Arlington, VA 22203-1416
  9.             USA
  10.  
  11.             Internet                  : Ferg_S@bls.gov
  12.             CompuServe ID             : 73377,1157
  13.             Internet                  : 73377.1157@compuserve.com
  14.             telephone (voice, not FAX): (703) 525-2241
  15.  
  16. =======================================================================
  17.  
  18. If you are planning to use Fdate with Windows NT, please see the section
  19. "/V WHEN RUNNING UNDER WINDOWS NT" (below), or read file FDATE_NT.TXT,
  20. which contains the same material.
  21.  
  22.  
  23. WHAT TO DO IF THIS DOCUMENTATION SEEMS TOO OVERWHELMING
  24. ========================================================
  25.  
  26. As Fdate has grown in functionality over the years, its documentation has
  27. also grown.  Lately I've been getting feedback from people who encounter
  28. Fdate for the first time, telling me that Fdate's documentation is so
  29. massive that it is overwhelming: they have no idea where to start, or how
  30. to use the documentation to help them figure out how to make Fdate do what
  31. they need to do.
  32.  
  33. If that is the situation you're in right now, take heart!  There is hope!
  34.  
  35. To help you get started using Fdate, I've created a much shorter file
  36. called FDATEBEG.TXT (FDATE beginners documentation), which shows how to use
  37. Fdate to do the things most users want to do.
  38.  
  39. So if you're trying to use Fdate for the first time, and feeling
  40. overwhelmed (or even if you're not feeling overwhelmed), I suggest that you
  41. read FDATEBEG.TXT.
  42.  
  43.                              Table of Contents
  44.  
  45. Page numbers in the WordPerfect version of FDATE.TXT (which is not
  46. distributed with FDATE) are lost in the conversion to ASCII format. 
  47. Nevertheless, these page numbers give you a rough idea of the relative
  48. locations of the different sections.
  49.  
  50.   WHAT TO DO IF THIS DOCUMENTATION SEEMS TOO OVERWHELMING. . . . . . . .  1
  51.   WHAT IS FDATE? . . . . . . . . . . . . . . . . . . . . . . . . . . . .  5
  52.      ANOTHER UTILITY NAMED "FDATE" . . . . . . . . . . . . . . . . . . .  6
  53.      OVERVIEW OF PARAMETERS. . . . . . . . . . . . . . . . . . . . . . .  7
  54.      OVERVIEW OF FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . .  9
  55.   FUNCTIONS: DETAILED DESCRIPTIONS . . . . . . . . . . . . . . . . . . . 11
  56.      DATE FORMATTING FUNCTIONS . . . . . . . . . . . . . . . . . . . . . 11
  57.      DATE ARITHMETIC FUNCTIONS . . . . . . . . . . . . . . . . . . . . . 12
  58.      MONTH DATE ARITHMETIC FUNCTIONS . . . . . . . . . . . . . . . . . . 13
  59.      WEEKDAY DATE ARITHMETIC FUNCTIONS . . . . . . . . . . . . . . . . . 14
  60.      DATE/TIME COMPARISON FUNCTIONS. . . . . . . . . . . . . . . . . . . 16
  61.      COMPARE-FUNCTION ERRORLEVELS. . . . . . . . . . . . . . . . . . . . 16
  62.      NUMERIC ARITHMETIC FUNCTIONS. . . . . . . . . . . . . . . . . . . . 17
  63.      DATE VALIDATION FUNCTION. . . . . . . . . . . . . . . . . . . . . . 19
  64.   STRING FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
  65.      GET and GETU (GET USER INPUT) FUNCTION. . . . . . . . . . . . . . . 20
  66.      GETK (GET KEYPRESS) FUNCTION. . . . . . . . . . . . . . . . . . . . 21
  67.        Specifying the Keymask. . . . . . . . . . . . . . . . . . . . . . 21
  68.        GetK Results also in ERRORLEVEL . . . . . . . . . . . . . . . . . 22
  69.        Modifying the Keymask . . . . . . . . . . . . . . . . . . . . . . 23
  70.        Displaying a User Prompt With GETK. . . . . . . . . . . . . . . . 23
  71.      SUBSTR (SUBSTRING) FUNCTION . . . . . . . . . . . . . . . . . . . . 24
  72.      LEN (LENGTH) FUNCTION . . . . . . . . . . . . . . . . . . . . . . . 26
  73.      UPPER FUNCTION. . . . . . . . . . . . . . . . . . . . . . . . . . . 26
  74.      ECHO FUNCTION . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
  75.      /J: JUSTIFYING OUTPUT . . . . . . . . . . . . . . . . . . . . . . . 27
  76.   DATE FORMATS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
  77.      SYMBOL CONVENTIONS. . . . . . . . . . . . . . . . . . . . . . . . . 29
  78.      PSEUDODATES . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
  79.   INPUT DATE FORMATS . . . . . . . . . . . . . . . . . . . . . . . . . . 31
  80.      ABSOLUTE DATE INPUT FORMATS . . . . . . . . . . . . . . . . . . . . 31
  81.      CALENDAR DATE INPUT FORMATS . . . . . . . . . . . . . . . . . . . . 32
  82.      BUSINESS JULIAN DATE INPUT FORMATS. . . . . . . . . . . . . . . . . 33
  83.      GETTING DATE/TIME A FILE WAS CREATED. . . . . . . . . . . . . . . . 34
  84.   OUTPUT DATE FORMATS. . . . . . . . . . . . . . . . . . . . . . . . . . 35
  85.      DAY-OF-WEEK AND MONTH OUTPUT FORMATS. . . . . . . . . . . . . . . . 37
  86.      MISCELLANEOUS OUTPUT FORMATS. . . . . . . . . . . . . . . . . . . . 37
  87.      LEAP-YEAR FLAG OUTPUT FORMAT. . . . . . . . . . . . . . . . . . . . 38
  88.      TIME OUTPUT FORMATS . . . . . . . . . . . . . . . . . . . . . . . . 38
  89.      BUSINESS JULIAN DATE OUTPUT FORMATS . . . . . . . . . . . . . . . . 39
  90.      ABSOLUTE DATE/TIME OUTPUT FORMATS . . . . . . . . . . . . . . . . . 40
  91.      /T: TIME OVERRIDE PARAMETER . . . . . . . . . . . . . . . . . . . . 41
  92.      /J: JUSTIFYING OUTPUT . . . . . . . . . . . . . . . . . . . . . . . 41
  93.   HOW TO PUT FDATE OUTPUT INTO AN ENVIRONMENT VARIABLE . . . . . . . . . 42
  94.      CALL A BATCH FILE . . . . . . . . . . . . . . . . . . . . . . . . . 42
  95.      USE AN ENVIRONMENT-MANIPULATION UTILITY . . . . . . . . . . . . . . 42
  96.      FDATE'S /V PARAMETER. . . . . . . . . . . . . . . . . . . . . . . . 43
  97.      /V WHEN RUNNING UNDER MICROSOFT WINDOWS . . . . . . . . . . . . . . 44
  98.      /V WHEN RUNNING UNDER WINDOWS NT. . . . . . . . . . . . . . . . . . 45
  99.        Turbo Professional: "Highly Recommended". . . . . . . . . . . . . 46
  100.      /V WHEN USING 4DOS, NDOS, AND UMB . . . . . . . . . . . . . . . . . 47
  101.   FDATE'S ERROR HANDLING . . . . . . . . . . . . . . . . . . . . . . . . 48
  102.   EXAMPLES OF HOW TO USE FDATE . . . . . . . . . . . . . . . . . . . . . 49
  103.      :01 Display Fdate output on screen. . . . . . . . . . . . . . . . . 49
  104.      :02 Redirect FDATE output to a file . . . . . . . . . . . . . . . . 49
  105.      :03 Put FDATE output in an environment variable using a batch file. 49
  106.      :04 Put FDATE output in an environment variable using /V parm . . . 49
  107.      :05 Put FDATE output in an environment variable using STRINGS . . . 49
  108.      :06 Put FDATE output in an environment variable using GET . . . . . 49
  109.      :07 Get user input. . . . . . . . . . . . . . . . . . . . . . . . . 50
  110.      :08 Get a user menu selection . . . . . . . . . . . . . . . . . . . 51
  111.      :09 Change a date from one format into another. . . . . . . . . . . 52
  112.      :10 Find the difference in days between two dates . . . . . . . . . 52
  113.      :11 Find the elapsed days/hours/minutes between two date/times. . . 53
  114.      :13 Find the elapsed years/months/days between two dates. . . . . . 56
  115.      :14 Determine how long it took a program to run . . . . . . . . . . 59
  116.      :15 Find years when a given date fell on a given day of the week. . 60
  117.      :16 Find calendar date corresponding to a "business Julian" date. . 62
  118.      :17 Set your PC's date to a business julian date. . . . . . . . . . 63
  119.      :18 Determine if parm %1 contains a valid date. . . . . . . . . . . 65
  120.      :19 "Roll your own" date format . . . . . . . . . . . . . . . . . . 65
  121.      :20 Find the 4th Thursday in November (Thanksgiving). . . . . . . . 66
  122.      :22 On a date, show what anniversary it is for some event . . . . . 66
  123.      :23 Show a list of holidays in a given year . . . . . . . . . . . . 66
  124.      :24 Show a list of Federal holidays in a given year . . . . . . . . 66
  125.      :25 Determine if a year is valid, and evenly divisible by 4 . . . . 67
  126.      :30 Compare a file's date to today's date . . . . . . . . . . . . . 67
  127.      :31 Compare two files' date/time  . . . . . . . . . . . . . . . . . 68
  128.      :32 Display a list of all files that were created/updated today.  . 69
  129.      :33 MIN_MATH.BAT -- "time arithmetic" in minutes. . . . . . . . . . 70
  130.      :34 TIME_SET.BAT -- "time arithmetic" -- set TIME . . . . . . . . . 71
  131.      :41 Delete files more than X days old (use a batch-file subroutine) 72
  132.      :42 Get date to tell PKZIP to compress files older than 30 days . . 77
  133.      :43 Loop through an array of environment variables. . . . . . . . . 78
  134.      :44 Do something on the last day (or last Friday) of the month. . . 79
  135.      :45 Get information about the month prior to the current month. . . 80
  136.      :46 Show the last Monday (or any other weekday) in this month . . . 80
  137.      :47 Show the last Monday in the month, for a series of months . . . 81
  138.      :50 Represent a date in 3 bytes of "extended hex" notation. . . . . 82
  139.      :51 Represent a date in a short (4-byte) format (technique #1). . . 82
  140.      :52 Represent a date in a short (4-byte) format (technique #2). . . 83
  141.      :53 Convert numbers to "extended hex" (XX) format . . . . . . . . . 83
  142.      :54 Customize Fdate for a language of your choice . . . . . . . . . 84
  143.      :55 Fergian.BAT (used in the previous example). . . . . . . . . . . 85
  144.      :61 DO-ONCE: Run apps when booting for the first time of the day. . 87
  145.      :62 Run specific software, depending on the day of the week . . . . 88
  146.      :63 Run a program at a specified time later in the day. . . . . . . 88
  147.      :66 Change a filename to contain today's date . . . . . . . . . . . 90
  148.      :67 Change a file's name to a name that contains today's date . . . 90
  149.      :68 Change a file's name to a name containing an absolute minute  . 90
  150.      :71 Extract the rightmost n characters of a string  . . . . . . . . 90
  151.      :72 Left-pad a number with zeroes, or a string with spaces. . . . . 90
  152.   HOW FDATE THINKS ABOUT DATES . . . . . . . . . . . . . . . . . . . . . 92
  153.      FDATE'S BUSINESS VIEW OF THE CALENDAR . . . . . . . . . . . . . . . 92
  154.      FDATE'S BASE DATE . . . . . . . . . . . . . . . . . . . . . . . . . 92
  155.      FDATE'S LEAP YEAR ALGORITHM . . . . . . . . . . . . . . . . . . . . 93
  156.      FDATE'S CENTURY-ASSUMPTION ALGORITHM. . . . . . . . . . . . . . . . 94
  157.      FDATE'S IMPLEMENTATION LIMITS . . . . . . . . . . . . . . . . . . . 94
  158.   DISTRIBUTION ISSUES. . . . . . . . . . . . . . . . . . . . . . . . . . 95
  159.      USE, REGISTRATION, AND DISTRIBUTION OF FDATE. . . . . . . . . . . . 95
  160.      TECHNICAL SUPPORT FOR FDATE . . . . . . . . . . . . . . . . . . . . 96
  161.      WHERE TO FIND THE MOST CURRENT VERSION OF FDATE . . . . . . . . . . 96
  162.      UPLOADING FDATE TO ELECTRONIC BULLETIN BOARDS . . . . . . . . . . . 96
  163.      CONTENTS OF THE FDATE.ZIP DISTRIBUTION FILE . . . . . . . . . . . . 96
  164.      RECENT FDATE REVISION HISTORY . . . . . . . . . . . . . . . . . . . 97
  165.  
  166. WHAT IS FDATE?
  167. ==============
  168. Fdate is a utility for doing date formatting and date arithmetic in DOS
  169. batch files.  There are a number of different ways to put FDATE's output
  170. into environment variables.  Once this has been done, the environment
  171. variables can be used and manipulated in many ways in the batch file.
  172.  
  173. FDATE is freeware, or what is technically known as "zero-cost shareware". 
  174. There is no requirement to register FDATE in any way.  For more details,
  175. see the DISTRIBUTION ISSUES section.
  176.  
  177. Here are some of the things you can do with FDATE.
  178.  
  179.     accept user input from the keyboard
  180.  
  181.     retrieve today's date in a variety of formats
  182.       place today's date into a file name
  183.  
  184.     reformat dates 
  185.        Output formats include common American and European formats, or you
  186.        can "roll your own" by manipulating environment variables.  Month
  187.        and weekday names can be produced in several languages (English,
  188.        French, German, Spanish).
  189.  
  190.     calculate when certain holidays occur in a given year
  191.  
  192.     do date arithmetic
  193.       determine the date N days before/after a given date
  194.       compare two dates to determine which is earlier
  195.       compare two dates to determine how many days apart they are
  196.  
  197.     determine if a year is a leap year
  198.     determine whether a year is evenly divisible by some number
  199.  
  200.     determine what day of the week a date falls on
  201.       run certain software only on certain days of the week
  202.  
  203.     retrieve the date/time from the date/timestamp of a file
  204.     do simple integer arithmetic (add, subtract, modulus)
  205.     calculate the time a piece of software takes to run
  206.     convert a calendar date to/from a "business julian" date
  207.  
  208.     extract a substring from an environment variable
  209.     right, left, or center justify a string
  210.  
  211. ANOTHER UTILITY NAMED "FDATE"
  212. =============================
  213.  
  214. There is another shareware utility named FDATE in circulation, written by
  215. Garrett A. Wollman.  Mr. Wollman's FDATE is a kind of "touch" utility that
  216. can be used to change a file's NAME (rather than its date/time stamp) to a
  217. certain date.  The Public Software Library in Houston distributes it under
  218. the name FDATE.ZIP.  PSL distributes my [Ferg's] FDATE under the name
  219. FDATESF.ZIP.  
  220.  
  221. As of April 1997, you can reach PSL by telephone (voice) at (713) 524-6394,
  222. by Compuserve at 74777,3465, or by the Web at www.pslweb.com.  
  223.  
  224. The most recent information I have is that Garrett Wollman can be reached
  225. at:
  226.      Garrett A. Wollman
  227.      7 Worcester Street
  228.      South Burlington, VT 05403
  229.      USA
  230.  
  231.      ...uunet!mimsy!aplcen!jhunix!gwollman
  232.      ...uunet!uvm-gen!tnl!gwollman   (summer)
  233.      gwollman@jhunix.hcf.jhu.edu
  234.  
  235. Both FDATEs have been in circulation under the name FDATE.ZIP for too long
  236. to make it practical to change the name of either one.  All that can be
  237. done is to warn you of a potentially confusing situation.  If you see a
  238. file named FDATE.ZIP, read the description of the file to determine which
  239. FDATE it is.  Checking the version numbers may also help-- as of April
  240. 1996, Ferg's FDATE is in version 9.3; Mr. Wollman's FDATE is in version
  241. 1.2.
  242.  
  243. OVERVIEW OF PARAMETERS
  244. ======================
  245.  
  246. FDATE accepts the following parameters:
  247.  
  248.        /F /A /B /I /O /P /S /N /D /L /V /T /Q /J /K /X
  249.  
  250. If the /F parameter is not present, FDATE displays a help screen.  
  251.      If you get FDATE's help screen when you don't expect it, you probably
  252.      forgot to specify the /F parameter or mistyped it.
  253.  
  254. Parameters can be in any order and upper or lower case.
  255.      Note that although function and format parms are not case sensitive,
  256.      they are "text sensitive".  If any characters are missing, added, or
  257.      mistyped, the parameter will be rejected.
  258.  
  259. What parameters are required (other than /F) depends on the function
  260. requested with the /F parameter.  Unnecessary parameters are simply
  261. ignored.
  262.  
  263.  
  264.  
  265. HERE IS A BRIEF SUMMARY OF WHAT EACH OF THE PARAMETERS MEANS
  266. ------------------------------------------------------------
  267.  
  268. /F   requests a particular FDATE function.  This is Fdate's most important
  269.      parameter.  See the OVERVIEW OF FUNCTIONS section, and the detailed
  270.      description of each Fdate function.
  271.  
  272. /A   For date functions, these two parameters are used to specify dates. 
  273. /B   For the ordinary arithmetic functions, these parameters are used to
  274.      specify numbers.  For date functions, if either of these parameters is
  275.      omitted, it defaults to today's date.
  276.  
  277. /Dday-of-week number (used only with W function)
  278.  
  279. /Ispecifies format of input date(s)
  280.   If the /I parameter is omitted, /Imm-dd-ccyy is assumed.
  281.  
  282. /J   specifies justification, length, and pad character
  283.   If the /J parameter is omitted, no justification formatting is done.
  284.  
  285. /K   The GETK function takes a /K "keymask" parameter that tells it which
  286.      keys to accept.
  287.  
  288. /L  specifies language of output.
  289.      /Lus   US (American) English-language output
  290.      /Lfr   French-language output
  291.      /Lgr   German-language output
  292.      /Lsp   Spanish-language output
  293.      If the /L parameter is omitted, /Lus [American English] is assumed.
  294.  
  295. /Nnumber of days (always a number)
  296.  
  297. /Ospecifies format of output date
  298.   If the /O parameter is omitted, /Od1 is assumed.
  299.  
  300. /Q   specifies a prompt string for a GET, GETU, or GETK function, or the
  301.      input string for a string-handling function (SUBSTR, LEN, UPPER).
  302.  
  303. /P   specifies a prefix string for the output
  304. /S   specifies a suffix string for the output
  305.      These optional parameters may always be specified or omitted.
  306.      They must be enclosed in single quotes, double quotes, or
  307.                   square brackets
  308.  
  309.      Note that "whitespace" will be removed from these strings, so
  310.      formatting of /P and /S strings cannot be controlled using spaces.  To
  311.      format strings, use periods or ASCII 255 (hex'ff') as filler.
  312.  
  313.        EXAMPLES
  314.           FDATE /Ff                /P"Today is "
  315.           FDATE /Fdif /B12-25-TTTT /P"It is " /S" days until Christmas"
  316.  
  317. /T   For date functions, /T overrides the time portion of the date on the
  318.      /A parm. (Note that it does NOT override the time portion of the date
  319.      on the /B parm.)  
  320.  
  321. /V   specifies that output is to be placed in an environment variable
  322.      rather than written to standard output.
  323.      If /V is specified but not followed by the name of an environment
  324.      variable, then /Vfdate is assumed, and output is placed in the FDATE
  325.      environment variable.
  326.  
  327. /X   Used only with the weekday arithmetic function (/Fw).  By default, if
  328.      if the date specified on the /A parm falls on the day of the week
  329.      specified on the /D parm, then the /A date is considered to be the
  330.      first date meeting the day-of-week criterion.  If the /X parm is
  331.      specified, then the /A date will NOT be considered to meet the
  332.      day-of-week criterion.  See the detailed discussion of weekday
  333.      arithmetic, below.
  334.  
  335. OVERVIEW OF FUNCTIONS
  336. =====================
  337.  
  338. Fdate's most important parameter is the function parameter, /F.  Here is a
  339. brief summary of the functions that may be specified on the /F parm, for
  340. example: /Fadd.  Detailed descriptions of each of the functions can be
  341. found on the next few pages.
  342.  
  343. If the /F parameter is omitted, it defaults to the null string, which
  344. causes Fdate to display its HELP screens.
  345.  
  346. f         Format the date in the /A parm into format specified in /O parm
  347.  
  348. add       Add the number of days in the /N parm to the date in the /A parm
  349.  
  350. sub       Subtract the number of days in the /N parm from the date in the
  351.           /A parm
  352.  
  353. dif       Return the number of days between dates in the /A and /B parms
  354.  
  355. w         Do date arithmetic in terms of weeks rather than days.  Using the
  356.           date in the /A parm, a number specified in the /N parm, and a
  357.           day-of-the-week number specified in the /D parm, return the date
  358.           of the /Nth /Day-of-the-week before (or after) /Adate.  
  359.  
  360. m         Do date arithmetic in terms of months rather than days.  Add the
  361.           number of months in the /N parm to the date in the /A parm.  /N
  362.           may be a negative number.
  363.  
  364. STRING-HANDLING FUNCTIONS
  365.  
  366. get       get user input from the keyboard, and produce it as output
  367.           Optionally, display a prompt string.
  368.  
  369. getu      same as get, but produce output converted to upper case
  370.  
  371. getk      get a keypress and produce it (converted to upper case)
  372.  
  373. len       produce the length of a string in the /Q parm
  374.  
  375. upper     convert the string in the /Q parm to upper case
  376.  
  377. e         Echo the strings on the /P and /S parameters.
  378.  
  379. substr    Extract a substring from the /Q parm, starting in column
  380.           specified on /A parm, for a length specified on /B parm.
  381.  
  382. DATE/TIME COMPARISON FUNCTIONS
  383.  
  384. comp      Compare the dates in the /A and /B parms. Return LT, EQ, or GT.
  385.  
  386. tcomp     Compare the times specified on the /A and /B parms.
  387.  
  388.  
  389. ORDINARY (AS OPPOSED TO DATE) ARITHMETIC FUNCTIONS
  390.  
  391.           Functions whose names begin with "#" do ordinary arithmetic, i.e.
  392.           arithmetic on numbers rather than dates.
  393.  
  394. #add      Add the integers specified on the /A and /B parms.  To do
  395.           subtraction, add a negative number to a positive number.
  396.  
  397. #dif      returns the difference between the integers specified on the /A
  398.           and /B parms. 
  399.  
  400. #comp     Compare the integers specified on the /A and /B parms.  Return
  401.           LT, EQ, or GT.
  402.  
  403. #mod      Modulus.  Divide the integer on the /A parm by the integer on the
  404.           /B parm, and return the remainder.  
  405.  
  406. #random   Random number.  Returns a random number between zero and the
  407.           number (an integer) specified on the /A parm.  
  408.  
  409. #mult     Multiply the integer on the /A parm by the integer on the /B
  410.           parm, and return the result.
  411.  
  412. #div      Divide the integer on the /A parm by the integer on the /B parm,
  413.           and return the result as a decimal number with two decimal
  414.           places.
  415.  
  416. #idiv     Integer division. Divide the integer on the /A parm by the
  417.           integer on the /B parm, and return the result as an integer.
  418.  
  419. #2xx      Convert an integer in the range of 0-35 to "extended hex" (XX)
  420.           notation.
  421.  
  422. FUNCTIONS: DETAILED DESCRIPTIONS
  423. ================================
  424.  
  425.  
  426. DATE FORMATTING FUNCTIONS
  427. =========================
  428.  
  429. FUNCTION  FDATE /Ffunc /Adate /Iformat /Oformat
  430. --------  -------------------------------------------
  431. format    this is a synonym for function "f"
  432.  
  433. f         returns /Adate in format specified by /Oformat
  434.           Since /Aformat and /Oformat can be different, the FORMAT
  435.           function is used to change a date from one format to another.
  436.           Because of the wide variety of output formats, the FORMAT
  437.           function can also be used to determine the day of week of the
  438.           date, whether the date is in a normal or leap year, etc.
  439.  
  440. EXAMPLES
  441.           FDATE /Ff /A19920101 /Iccyymmdd /O"mn zd, ccyy"
  442.           FDATE /Ff       /Atoday         /Od1
  443.           FDATE /Fformat  /Atoday         /Od1
  444.           FDATE /Ff /If /Afdate.exe /P"FDATE.EXE last updated: " /Ofull
  445.  
  446. DATE ARITHMETIC FUNCTIONS
  447. =========================
  448.  
  449. Internally, numbers in Fdate are stored in Turbo Pascal's LONGINT datatype,
  450. which means that Fdate can accept numbers up to 9 digits long.
  451.  
  452. FUNCTION  FDATE /Ffunc /Nnumdays /Adate /Iformat /Oformat
  453. --------  -------------------------------------------
  454. add       Adds      /Ndays to   /Adate, produces date in /Oformat format
  455. sub       Subtracts /Ndays from /Adate, produces date in /Oformat format
  456.  
  457.           EXAMPLES
  458.           FDATE /Fadd /N90 /A01-01-1992 /Imm-dd-ccyy /Od1
  459.           FDATE /Fsub /N90 /A01-01-1992 /Imm-dd-ccyy /Od1
  460.           FDATE /Fadd /N90 /Atoday                   /Od1
  461.  
  462. dif       Returns number of days between /Adate and /Bdate
  463.           Order of the two dates is not significant.
  464.  
  465.           NOTE THAT:
  466.           For DIF, both dates must be in the SAME format, the input format
  467.           specified in /Iformat.  If the two dates are not in the same
  468.           format, you must first reformat one of the dates using the /Ff
  469.           function, then use DIF to get their difference.
  470.  
  471.           EXAMPLES
  472.           FDATE /Fdif /A01-01-1992 /B11-11-1992  /Imm-dd-ccyy
  473.           FDATE /Fdif /A11-11-1992 /B01-01-1992  /Imm-dd-ccyy
  474.           FDATE /Fdif /Atoday      /B01-01-1992  /Imm-dd-ccyy
  475.  
  476. MONTH DATE ARITHMETIC FUNCTIONS
  477. ===============================
  478.  
  479. FUNCTION  FDATE /Ffunc /Nnumdays /Adate /Iformat /Oformat
  480. --------  -------------------------------------------
  481. m         [month arithmetic]
  482.  
  483.           This function adds /N months to /Adate, and produces a date in
  484.           /Oformat format.  It can be used to do monthly subtraction by
  485.           making the number in the /N parameter a negative number.
  486.  
  487.           EXAMPLES
  488.  
  489.           FDATE /Fm /N1  /A03-15-1992 /Imm-dd-ccyy /Omm-dd-ccyy
  490.                   produces:   04-15-1992
  491.  
  492.           FDATE /Fm /N-1 /A03-30-1991 /Imm-dd-ccyy /Omm-dd-ccyy
  493.                   produces:   02-28-1991
  494.  
  495.           FDATE /Fm /N-1 /A03-30-1992 /Imm-dd-ccyy /Omm-dd-ccyy
  496.                   produces:   02-29-1992
  497.  
  498.  
  499.           Note that a too-simple algorithm for month arithmetic can produce
  500.           non-existent dates.  Subtracting a month from March 30, 1991 (as
  501.           in the second example) could produce a result of February 30,
  502.           1991, a date which cannot exist.  
  503.  
  504.           Fdate's month arithmetic is more sophisticated than that.  If
  505.           Fdate finds that a simple month-arithmetic operation produces an
  506.           invalid date, it subtracts the minimum number of days required to
  507.           produce a valid date.  
  508.  
  509.           Thus, in the second example, it produces February 28, 1991, the
  510.           last date in February, 1991.  In the third example, it produces
  511.           February 29, 1992 because 1992 is a leap year.  
  512.  
  513.  
  514. Note that telling Fdate to add 12 months to February 29, 1992 produces a
  515. result of February 28, 1993, since 1993 is not a leap year.  See Peter G.
  516. Neumann's INSIDE RISKS column in COMMUNICATIONS OF THE ACM, June 1992 (Vol.
  517. 35, No. 6), entitled "Leap-Year Problems":
  518.  
  519.   Prime Computer's MAGSAV failed at midnight [on Feb 29, 1992]...  G. M.
  520.   Lack noted that MAGSAV probably failed on leap-day because it tried to
  521.   increment the year by one to set a tape label expiration date, and the
  522.   resulting nonexistent date of Feb 29, 1993 threw it for a loop.
  523.  
  524. WEEKDAY DATE ARITHMETIC FUNCTIONS
  525. =================================
  526.  
  527. FUNCTION  FDATE /Ffunc /Adate /Iformat /Oformat /Ddow#  /Ndow-count
  528. --------  -----------------------------------------------------------
  529.  w[week arithmetic]
  530.           This function provides a way of doing date arithmetic in terms of
  531.           weeks rather than days.
  532.  
  533.           This function accepts a date specification in parm /A and
  534.           returns the date of the /Nth /Day-of-the-week
  535.           before or after /Adate.  For example:
  536.  
  537.           If    /A specifies November 14, 1992
  538.                 /D specifies the number for Thursday (i.e., 5)
  539.                 /N specifies a week count of 3
  540.           then /Fw returns the date of the third Thursday after
  541.           November 14, 1992. (See full example, below)
  542.  
  543.           Note that /N may be negative.  If, in the above example, /N
  544.           is specified as -3, then Fdate returns the date of the third
  545.           Thursday BEFORE November 14, 1992.
  546.  
  547.           The acceptable values for /N (number of weeks) is in
  548.           the range of 99..-99.  A value of zero (i.e. /N0) is invalid.
  549.  
  550.    A BIT OF TRICKINESS WITH WEEKDAY ARITHMETIC
  551.      There is a small dilemma inherent in the notion of weekday arithmetic. 
  552.      If the date specified on the /A parm falls on the same day of the week
  553.      (say, Thursday) as the day of the week that was specified on the /D
  554.      parm, should (or should not) the /A date be considered the first date
  555.      that meets the day-of-week criterion?  For example, if day X is a
  556.      Thursday, and we specify that we want the first Thursday ("/N1 /D5")
  557.      from day X, should we get day X itself, or the Thursday that is 7 days
  558.      after day X? 
  559.  
  560.      Depending on what you're trying to do, one or the other kind of
  561.      behavior will be preferable.  Starting with version 9.2, FDATE
  562.      supports both kind of processing.  When using the weekday arithmetic
  563.      function (/Fw), you can determine the kind of processing that takes
  564.      place by specifying (or omitting) the /X (exclude) parm.  That is, if
  565.      the date specified on the /A parm falls on the day of the week
  566.      specified on the /D parm, then...
  567.  
  568.      IF THE /X PARM IS NOT PRESENT ...
  569.      then the /A date will be considered to be the first date meeting the
  570.      day-of-week criterion.  For example, suppose that /D specified
  571.      Thursday and /A specified Thursday, November 14, 1992.  If /N was 1 or
  572.      -1, then the output date would be the same as the input date, i.e.
  573.      Thursday November 14, 1992.
  574.  
  575.      IF THE /X PARM IS PRESENT ...
  576.      then the /A date will be EXCLUDED from consideration when looking for
  577.      the first day to meet the day-of-week criterion.  For example, suppose
  578.      that /D specified Thursday and /A specified Thursday November 14,
  579.      1992.  If /N was 1, then the output date would be the following
  580.      Thursday, November 21, 1992.  If /N was -1, then the output date would
  581.      be the preceding Thursday, November 7, 1992.
  582.  
  583.  
  584. EXAMPLES
  585.      find date of Thanksgiving (4th Thursday in November) in 1992
  586.          FDATE /Fw /A11-01-1992 /Imm-dd-ccyy /D5 /N4 /Od1
  587.      returns: Thursday November 26, 1992
  588.  
  589.      find the beginning of the work-week (Monday, 2nd day of week)
  590.      AFTER Thanksgiving, 1992
  591.          FDATE /Fw /A11-26-1992 /Imm-dd-ccyy /D2 /N1 /Od1
  592.  
  593.      find the beginning of the work-week (Monday, 2nd day of week)
  594.      BEFORE Thanksgiving, 1992
  595.          FDATE /Fw /A11-26-1992 /Imm-dd-ccyy /D2 /N-1 /Od1
  596.  
  597.      find last Friday's date (even if today is Friday)
  598.         FDATE /Fw /At /D6 /N-1 /X  /P"Last Friday was: "
  599.  
  600. DATE/TIME COMPARISON FUNCTIONS
  601. ==============================
  602.  
  603. FUNCTION  FDATE /Ffunc /Adate /Bdate /Iformat
  604. --------  -------------------------------------------
  605. comp      compares the dates (time granularity = 1 day)
  606.           specified on the /A and /B parms.
  607.           returns         when
  608.             LT            /A  is less than    (earlier than) /B
  609.             EQ            /A  is equal to     (same as)      /B
  610.             GT            /A  is greater than (later than)   /B
  611.  
  612.           In addition, the errorlevel is set to a special value:
  613.             LT = 101     EQ = 102     GT = 103
  614.  
  615.  
  616.  
  617. tcomp     compares the times (time granularity = 1 second)
  618.           specified on the /A and /B parms.
  619.           This is useful when input format /If (file) is specified.
  620.           It can be used to compare the timestamps of two files and
  621.           determine which is older.
  622.               EXAMPLE: Fdate /Ftcomp /If /Amyfile.1 /Byourfile.1
  623.  
  624.           returns         when
  625.             LT            /A  is less than    (earlier than) /B
  626.             EQ            /A  is equal to     (same as)      /B
  627.             GT            /A  is greater than (later than)   /B
  628.  
  629.           In addition, the errorlevel is set to a special value:
  630.             LT = 101     EQ = 102     GT = 103
  631.  
  632.  
  633.  
  634. COMPARE-FUNCTION ERRORLEVELS
  635. ============================
  636.  
  637. Starting with version 8.3, Fdate's "comparison" functions (comp, tcomp,
  638. #comp) return distinct errorlevels as well as distinct output strings:
  639.  
  640.           returns         errorlevel
  641.             LT            101
  642.             EQ            102
  643.             GT            103
  644.  
  645. NUMERIC ARITHMETIC FUNCTIONS
  646. ============================
  647.  
  648. Note that all of Fdate's arithmetic functions operate on integers.  A
  649. decimal number on an input parameter will be rejected, and an error message
  650. will be displayed.
  651.  
  652. FUNCTION  FDATE /Ffunc /Anum  /Bnum
  653. --------  -------------------------------------------
  654.  
  655. #add      returns the sum of the integers specified
  656.           on the /A and /B parms.  Can be used to calculate the
  657.           "absolute" minute(second, date) in the future from a given
  658.           "absolute" minute(second, date).   Also useful in generating
  659.           sequences of numbers and looping (see EXAMPLES).
  660.  
  661. #sub      (not supported)
  662.           Fdate does not provide a numeric subtraction operation as such. 
  663.           To do subtraction, add two numbers, one of which is a negative
  664.           number.  For example, to subtract 3 from 2:
  665.               FDATE /F#add /A2 /B-3          [ returns: -1 ]
  666.  
  667. #dif      returns the difference between the integers specified on the /A
  668.           and /B parms.  #dif is the same as subtraction in which the
  669.           smaller number is subtracted from the larger number; it will
  670.           never return a negative number.  It can be used to calculate the 
  671.           number of minutes(seconds, days) between two "Absolute"
  672.           minutes(seconds, dates).
  673.  
  674. #comp     compares the integers specified on the /A and /B parms.
  675.           returns         when
  676.             LT            /A  is less    than /B
  677.             EQ            /A  is equal   to   /B
  678.             GT            /A  is greater than /B
  679.  
  680.           In addition, the errorlevel is set to a special value:
  681.             LT = 101     EQ = 102     GT = 103
  682.  
  683. #mod      divides the integer on the /A parm by the integer on the /B parm,
  684.           and returns the remainder.  
  685.  
  686.           This is useful for determining whether a number is evenly
  687.           divisible by some other number.  If the remainder is 0, then /A
  688.           is evenly divisible by /B.  If a year is evenly divisible by 4,
  689.           for example, then it is an American election year.  If it is
  690.           evenly divisible by 100, then it is a century year, etc.
  691.  
  692.  
  693. #mult     multiplies the integer on the /A parm by the integer on the /B
  694.           parm, and returns the result.
  695.  
  696. #div      (division) divides the integer on the /A parm by the integer on
  697.           the /B parm, and returns the result as a decimal number, with two
  698.           digits to the right of the decimal.
  699.  
  700.           This is useful for dividing a number (representing the number of
  701.           minutes in some period) by 60 to get the length of the period
  702.           expressed in terms of hours, or by 1440 to get the length of the
  703.           period expressed in terms of days.  Or you could divide a number
  704.           of days by 7 to get the number of weeks, etc.
  705.  
  706.  
  707. #idiv     (integer division) divides the integer on the /A parm by the
  708.           integer on the /B parm, and returns the result as an integer.
  709.  
  710.           This is useful, especially in conjunction with the #mod function,
  711.           for converting a number of minutes into a number of hours and
  712.           minutes, or days and hours and minutes.  See the EXAMPLES
  713.           section, below.
  714.  
  715. #2xx      (convert number to "extended hex" format)
  716.           "Extended hexadecimal" (XX) notation uses all of the digits, and
  717.           all of the letters of the alphabet, to express numbers in the
  718.           range of 0 to 35 as a single character.  
  719.  
  720.           This function takes a number supplied on parameter /A, and
  721.           returns a single character in extended hex notation.  The input
  722.           number should be in the range of 0-35.  A number of less than 0
  723.           or larger than 35 is rejected as an error (returns "ERROR" and
  724.           errorlevel of 1).
  725.  
  726.           EXAMPLE: Fdate /F#2xx /A35    =====> returns the letter Z
  727.  
  728. DATE VALIDATION FUNCTION
  729. ========================
  730.  
  731. v    If the date specified on the /A parm is valid, produces "" (the null
  732.      string).  Otherwise, produces "ERROR" and a non-zero errorlevel by
  733.      triggering Fdate's error-handling function.  (See the section on
  734.      FDATE'S ERROR HANDLING, later in this documentation.)
  735.  
  736.      When using the /Fv parameter, you will almost always want to check
  737.      success of the date validation by checking the errorlevel, and to
  738.      redirect Fdate's output to NUL (so that when it writes the null
  739.      string, it does not produce a blank line on your screen).
  740.  
  741.      When processing an input date, Fdate does not reject all invalid
  742.      dates: specifically, it is very forgiving about the number in the day-
  743.      of-the-month part of input dates.  It will accept, for example,
  744.      19931144 (November 44, 1993 in CCYYMMDD format) and process it quite
  745.      happily (as December 14, 1993).  This is not a bug, it is a feature. 
  746.      This feature provides one way (admittedly a crude one) of doing date
  747.      arithmetic.  The date part (JJJ) of a Business Julian input date can
  748.      be used in the same way.  
  749.  
  750.      This feature can be a drawback, however, if you want to be sure that
  751.      some date (say a date that a user entered as an input parameter) is
  752.      valid.  The /Fv function provides a way of completely checking a date
  753.      for validity.  It will, for example, reject November 44, 1993 as
  754.      invalid. 
  755.  
  756.  
  757. STRING FUNCTIONS
  758. ================================
  759.  
  760. GET and GETU (GET USER INPUT) FUNCTIONS
  761. =======================================
  762.  
  763. get  get user input
  764. getu get user input (uppercase)
  765.  
  766.      These functions wait for the user to enter an input string, terminated
  767.      by a press of the ENTER key.  Then Fdate simply produces that same
  768.      input string (or in the case of GETU, that input string in all upper
  769.      case) as its output.  
  770.  
  771.      If the /Q prompt-string parameter is specified, then the prompt string
  772.      is displayed, but a NEWLINE is not written to the screen before
  773.      waiting for the user's input.
  774.  
  775.      As with Fdate's other forms of output, this output can be displayed,
  776.      redirected to a file, or (if your environment supports Fdate's /V
  777.      parameter) placed into an environment variable.
  778.  
  779.      This "get" function provides no edit mask for input -- Fdate will
  780.      accept anything.  The situation is helped by the fact that Fdate also
  781.      provides a validate function (/Fv) which can be used to validate the
  782.      user input, so that one can:
  783.  
  784.           1.   use /Fget to get user input and place it in an environment
  785.                variable 
  786.           2.   use /Fv to validate the date in the Evar
  787.           3.   use the rest of the batch file to process the user input
  788.  
  789.      See examples: "Get user input" and FORATIM2.BAT
  790.  
  791.      For a program that provides more sophisticated functions for getting
  792.      user input in batch files (type checking, edit masks, etc.), I
  793.      recommend Bob Stephan's shareware program GET, which is described
  794.      elsewhere in this documentation.
  795.  
  796. GETK (GET KEYPRESS) FUNCTION
  797. =======================================
  798. getK get keypress 
  799.  
  800.      This function waits for the user to press an acceptable key, then
  801.      produces the key as its output.  If the key pressed is a letter, then
  802.      the letter is returned IN UPPER CASE.  This feature is designed to
  803.      support simple "pick a menu selection" processing in batch files.
  804.  
  805.      The GETK function takes a /K "keymask" parameter that tells it which
  806.      keys to accept.  If the user presses an unacceptable key (i.e. one
  807.      that is not in the keymask), the keypress is ignored.
  808.  
  809.      If no /K parm is specified, the default keymask is:
  810.              ABCDEFGHIJKLMNOPQRSTUVWXYZx
  811.      That is, the default keymask will accept letters and the ESCAPE key.
  812.  
  813.   Specifying the Keymask
  814.  
  815.      NOTE THAT THE VALUES SPECIFIED ON THE /K PARM ARE CASE-SENSITIVE.  
  816.  
  817.      The keymask may contain numbers, uppercase letters, and any of the
  818.      other printable characters on the keyboard.  
  819.  
  820.      There is no way to tell FDATE to accept "special" keypresses such as
  821.      function keys, ALT or CONTROL keys, arrow keys, etc.
  822.  
  823.      If the keymask contains an uppercase letter (e.g. "A"), and the user
  824.      presses the corresponding unshifted letter (e.g. "a"), then the
  825.      keypress will be accepted and the uppercase letter will be returned.
  826.  
  827.      The keymask may contain the following lowercase letters, which have
  828.      special meanings:
  829.  
  830.        x  represents the ESCAPE key
  831.        e  represents the ENTER (RETURN) key
  832.        z  [a place-holder character]
  833.  
  834.             Lowercase "z" will be ignored when FDATE decides which
  835.             keypresses are acceptable.  Its presence in the keymask will
  836.             affect the positions of other characters in the keymask, and
  837.             hence the ERRORLEVEL that FDATE returns when the user presses
  838.             an acceptable key.  (For the uses of "z", see "GetK Results
  839.             also in ERRORLEVEL" and "Modifying the Keymask", below.)
  840.  
  841.      All other lowercase letters are reserved for possible future use.  In
  842.      the current release of FDATE, they are treated like lowercase "z".
  843.  
  844.      EXAMPLE:  If a keymask of "/kXx" was specified, then if the user
  845.                pressed the (shifted or unshifted) "X" key, then uppercase
  846.                "X" would be returned.  If he pressed the ESCAPE key, then
  847.                lowercase "x" would be returned.
  848.  
  849.   GetK Results also in ERRORLEVEL
  850.  
  851.      When the GETK function returns a key, it sets the DOS errorlevel to a
  852.      value corresponding to the position of that key in the keymask.  For
  853.      example, with keymask of "/kABx", if the user presses:
  854.  
  855.           "A": value returned will be "A", errorlevel will be 1
  856.           "B": value returned will be "B", errorlevel will be 2
  857.        ESCAPE: value returned will be "x", errorlevel will be 3
  858.  
  859.      If the user presses CONTROL+BREAK, FDATE will abort and return
  860.      errorlevel 255.
  861.  
  862.      Here is an example batch file:
  863.      ==================================================================
  864.   @echo off
  865.   cls
  866.   echo Demonstration of FDATE's GETK (get keypress) function
  867.   echo Press CONTROL+BREAK to end
  868.   :top
  869.   echo.
  870.   fdate /fGetK /P"You pressed: " /Q"Press a key: "  /K"12ABxe "
  871.   if errorlevel 1  if not errorlevel 2  echo errorlevel : 1
  872.   if errorlevel 2  if not errorlevel 3  echo errorlevel : 2
  873.   if errorlevel 3  if not errorlevel 4  echo errorlevel : 3
  874.   if errorlevel 4  if not errorlevel 5  echo errorlevel : 4
  875.   if errorlevel 5  if not errorlevel 6  echo errorlevel : 5
  876.   if errorlevel 6  if not errorlevel 7  echo errorlevel : 6
  877.   if errorlevel 7  if not errorlevel 8  echo errorlevel : 7
  878.   if errorlevel 255 echo ERRORLEVEL 255
  879.   if errorlevel 255 goto endit
  880.   goto top
  881.   :endit
  882.      ==================================================================
  883.  
  884.      Note that the keymask may contain blanks if the keymask is enclosed in
  885.      quotes (as in this example batch file).  But remember that Fdate
  886.      eliminates redundant spaces when obtaining its parameter input, so you
  887.      should never include more than one blank in your keymask.
  888.  
  889.   Modifying the Keymask
  890.  
  891.      It is often necessary to make program modifications during the life of
  892.      a batch file.  If you are using the GETK function and testing the
  893.      errorlevel rather than the environment, then the insertion or deletion
  894.      of characters into the existing keymask will change the errorlevels
  895.      returned by the following characters in the keymask.  This will force
  896.      you to re-write the errorlevel tests, which may be a big job if the
  897.      keymask is long.
  898.  
  899.      Here are some tips on how to avoid this work:
  900.  
  901.          When ADDING a character to the keymask, always add it at the END
  902.           of the keymask.
  903.  
  904.          When DELETING a character from the keymask, do not actually
  905.           delete it.  Instead, replace it by a lowercase "z".
  906.  
  907.  
  908.  
  909.   Displaying a User Prompt With GETK
  910.  
  911.      The /Q (user prompt) parameter is especially handy when used in
  912.      conjunction with the GETK function.  If the /Q prompt-string parameter
  913.      is specified (as in the example batch file, above), then the prompt
  914.      string is displayed, but a NEWLINE is not written to the screen before
  915.      waiting for the user's keypress.
  916.  
  917.      For a program that provides more sophisticated "get key" functions for
  918.      batch files, I recommend Bob Stephan's shareware program GET, which is
  919.      described elsewhere in this documentation.
  920.  
  921. SUBSTR (SUBSTRING) FUNCTION
  922. ===============================
  923.  
  924. substr
  925.      This function returns a substring of the string supplied in the /Q
  926.      parm, starting in the column supplied in the /A parm, for a length
  927.      supplied in the /B parm.  
  928.  
  929.      The start column specified in the /A parm may be a negative number; if
  930.      it is, then the start column is calculated from the end of the string
  931.      rather than from the beginning.  This feature makes it easy to extract
  932.      the rightmost characters of a string.  
  933.  
  934.                Specifically, when the ParmA is negative, the start position
  935.                is calculated using the following formula:
  936.  
  937.                       StartColumn = length(ParmQ) + 1 + ParmA
  938.  
  939.              Example:   Fdate /Fsubstr  /A-2 /Qabcd
  940.                       StartColumn = length(ParmQ) + 1 + ParmA
  941.                       StartColumn =      4        + 1 + (-2)     = 3  
  942.  
  943.   If /Q is omitted, Fdate reports an error.
  944.  
  945.   If /A is zero, Fdate reports an error.
  946.   If /A is omitted, it defaults to 1 (that is, the start of the string).
  947.   If /A is negative,  and longer than the length of the string, then the
  948.                       start column is 1 (the start of the string)
  949.  
  950.      If /B (length) is so great that it exceed the length of the /Q input
  951.      string, then only the remainder of the string is returned.
  952.  
  953.   If /B is zero, Fdate returns a null string.
  954.   If /B is omitted, it defaults to 999.
  955.  
  956.      EXAMPLES:
  957.           Fdate /Fsubstr /A7 /B2 /Q"STEVE FERG"   ===> "FE"
  958.            Fdate /Fsubstr /A7     /Q"STEVE FERG"   ===> "FERG"
  959.            Fdate /Fsubstr     /B5 /Q"STEVE FERG"   ===> "STEVE"
  960.  
  961.      EXAMPLES using a negative start position:
  962.           Fdate /Fsubstr /a-6 /B3 /Q"1994 Jun 03"   ===> "Jun                   
  963.  
  964.           rem extract the rightmost 6 characters of a string
  965.            Fdate /Fsubstr /a-6     /Q"1994 Jun 03"   ===> "Jun 03"
  966.  
  967.   rem pad YEAR environment variable to the left with zeroes, 
  968.   rem to make sure it is 4 bytes long
  969.   Fdate /Fsubstr /A-4 /q0000%year% /vyear
  970.  
  971.  
  972.      REMEMBER that Fdate eliminates redundant spaces when obtaining its
  973.      parameter input:
  974.  
  975.            Fdate /Fsubstr /A7     /Q"STEVE FERG"      ===> "FERG"
  976.            Fdate /Fsubstr /A7     /Q"STEVE  FERG"     ===> "FERG"
  977.            Fdate /Fsubstr /A7     /Q"STEVE    FERG"   ===> "FERG"
  978.  
  979. LEN (LENGTH) FUNCTION
  980. =====================
  981.  
  982. len       Produces a number that is the length of the string on the /Q
  983.           parm.
  984.  
  985.  
  986. UPPER FUNCTION
  987. ===============
  988.  
  989. upper     Produces the string on the /Q parm, converted to upper case.
  990.  
  991.  
  992.  
  993. ECHO FUNCTION
  994. =============
  995.  
  996. e    Produces only the strings specified using the /Q, /P, and /S
  997.      parameters.  Justification, if specified using the /J parm, is applied
  998.      only to the string, if any, supplied on the /Q parm.
  999.  
  1000. You can use /Fe for situations in which you want Fdate to produce output
  1001. that doesn't include any sort of date.  In these cases, Fdate functions
  1002. just like the DOS "echo" command.  
  1003.  
  1004. The /Fe function is especially useful in conjunction with the /J (justify)
  1005. parm (see below).
  1006.  
  1007. One nifty feature of /Fe (although one that will be of interest only to
  1008. extreme batch-file power users) is its ability, when used in conjunction
  1009. with /V, to put a character into an environment variable that the SET
  1010. command would not accept: characters such as an equal-sign "=" , the
  1011. redirection symbol ">", and the pipe symbol "|".
  1012.  
  1013. /J: JUSTIFYING OUTPUT
  1014. ==========================
  1015. Using the /J (justify) parameter, it is possible to right, center, or left-
  1016. justify FDATE's output, truncate it, or pad it with a certain character.   
  1017.  
  1018. Note that /J is not a function, but a parameter.  The /J parameter may be
  1019. used in conjunction with any of FDATE's functions.  (It is discussed here,
  1020. with the string-handling functions, because that's where it seemed most at
  1021. home.)
  1022.  
  1023. Justification takes place AFTER the strings specified on the /P (prefix)
  1024. and /S (suffix) parms have been added to the output.
  1025.  
  1026.   The format of the /J parm is:  /J"tp##"         where
  1027.  
  1028.   t is a single character indicating the type of justification desired:
  1029.    Rright
  1030.    Lleft
  1031.    Ccentered
  1032.  
  1033.   p  is a single character specifying the character to be used to pad the
  1034.      output out to the desired length.  The most common values for this
  1035.      character will be the period (".") and the blank.  In order for a
  1036.      blank to be recognized as a pad character (and not to be taken as the
  1037.      terminator of the /J-parm value), the /J-parm value must be enclosed
  1038.      in single or double quotes, e.g.:   /J"C 79"
  1039.  
  1040. ##   is a number that specifies the length of the field within which
  1041.      justification should take place.  This must be a number between 1 and
  1042.      240.
  1043.  
  1044.      If ## is less than the length of the un-justified output string, then
  1045.      the un-justified output string will be truncated to ## characters,
  1046.      starting at the point specified by the justification type (i.e. at the
  1047.      right, left, or center of the un-justified output string).
  1048.  
  1049.  
  1050.  SOME USES FOR THE /J PARM
  1051.  
  1052.   (Most of these uses are illustrated in HOLIDAYS.BAT, which is included
  1053.   in the FDATE distribution ZIP file.)
  1054.  
  1055.   In conjunction with the "echo" function (/Fe), the /J parm can be used
  1056.   to justify any value that you wish, not just output dates created by
  1057.   Fdate.  Put the value to be justified in the /Q parm.  Put a title, for
  1058.   example, as the value of the /Q parm, and specify center justification,
  1059.   padded with spaces, to a length of 79 characters (/J"c 79").  This will
  1060.   display the title, centered on the screen.
  1061.  
  1062.   If you use the "echo" function and the /J parm, and specify the /Q parm
  1063.   but do not specify a value for it, then only the pad character will be
  1064.   displayed. (That is, the null string will be padded with the pad
  1065.   character to the desired length.) 
  1066.  
  1067.   EXAMPLE:  This is a handy way to draw horizontal lines of dashes,
  1068.             dots, or any other desired character.
  1069.                     FDATE /FE  /Q  /JC-79 
  1070.  
  1071.   The /J parm can be used to left-pad a number with zeroes.
  1072.  
  1073.   EXAMPLE:  Many of Fdate's input formats require the year to be in
  1074.             complete 4-digit CCYY format.  If your batch file obtains a
  1075.             value for YEAR from the user, the user might enter a YEAR
  1076.             that is less than 1000.  You can add leading zeroes to YEAR
  1077.             by right justifying it, padded it with '0' to a length of 4. 
  1078.             
  1079.   FDATE  /Fe  /Q%year%  /JR04  /vyear
  1080.  
  1081.   Because /J can be used to truncate a string to a specified length, it
  1082.   can be used to extract the rightmost, leftmost, or centermost ##
  1083.   characters of a string. 
  1084.  
  1085.  
  1086. EXAMPLES
  1087.  
  1088.   Fdate /Fe /J"C 79" /Q"SCREEN TITLE"
  1089.      Fdate's output is not put into an environment variable, so it will be
  1090.      displayed on the screen.  This command will echo the string "SCREEN
  1091.      TITLE" to the screen, centered in a field 79 characters long (that is,
  1092.      centered on the screen), and padded to the left and right with blanks.
  1093.  
  1094.   Fdate /Fe /J"L.40" /Q"Next report due date" /Vtitle
  1095.   Fdate /fadd /N60  /Od1 /Q"%title% "
  1096.      The first command left-justifies "Next report due date" in a string 40
  1097.      characters wide, padded to the right with periods, and puts it into
  1098.      the TITLE environment variable.  In the second step, the TITLE
  1099.      environment variable is used as the label for a date 60 days in the
  1100.      future.  In the second step, note the space between the end of %title%
  1101.      and the trailing double-quote.  This leaves a nice space between the
  1102.      dot leader and the date.
  1103.  
  1104.   For more examples, see HOLIDAYS.BAT.
  1105.  
  1106. DATE FORMATS
  1107. ============
  1108.  
  1109. SYMBOL CONVENTIONS
  1110. ==================
  1111.  
  1112. The following symbols are used in specifying date formats:
  1113.  
  1114. SYMBOL  EXAMPLE   MEANING
  1115. ------  -------   -------------------------------------
  1116. cc        19      century
  1117. yy        93      year
  1118. mm        02      month
  1119. zm         2      month without leading zero
  1120. dd        08      day
  1121. zd         8      day   without leading zero
  1122. mn       February month name
  1123. mn3      Feb      month name, first 3 characters only
  1124. dow      Tuesday  day of week
  1125. dow3     Tue      day of week, first 3 characters only
  1126. dow#      3       day of week as a number (Sunday=1, Monday = 2, etc.)
  1127. today             is a "pseudodate" representing the current date
  1128. t                 is an alias for the "today" pseudodate
  1129. hh:mm    09:05    hours and minutes
  1130. hhmm     0905     hours and minutes
  1131. ss        13      seconds
  1132.  
  1133.  
  1134.  
  1135. PSEUDODATES
  1136. ===========
  1137.  
  1138. t (or today)
  1139.           can be used with either /A or /B, e.g. /Atoday or /At.
  1140.           This is the default for both /A and /B.  That is, if /A is not
  1141.           specified, /At is assumed, and the same for /B.
  1142.  
  1143.           NOTE THAT
  1144.           "Today" as a date specification operates independently of any
  1145.           input format.  You need to specify an input format (either
  1146.           explicitly via the /I parameter, or implicitly by accepting the
  1147.           default value of /I) only for input dates that are supplied to
  1148.           Fdate in some other way than via the "today" pseudodate: as a
  1149.           date literal, a filename, etc.
  1150.  
  1151. EXAMPLES:
  1152.           rem Get the date that is 90 days from today
  1153.           FDATE /Fadd /N90 /Atoday /Omm-dd-ccyy
  1154.           FDATE /Fadd /N90 /At     /Omm-dd-ccyy
  1155.  
  1156.           rem determine if this year is a leapyear
  1157.           FDATE /Ff /At /OLY
  1158.  
  1159.  
  1160.  
  1161.  
  1162. tttt      When used in place of a 4-digit CCYY string, "tttt"
  1163.           will cause Fdate to use today's 4-digit year (CCYY).
  1164.  
  1165. tt        When used in place of a 2-digit DD, MM, or YY string,
  1166.           "tt" will cause Fdate to use today's day-of-the-month,
  1167.           month, or 2-digit year, respectively.
  1168.  
  1169.           Note that "tt" can NOT be used for the YY portion of a CCYY
  1170.           input year.  The following, for example, is NOT valid:
  1171.                FDATE /Ff /Imm-dd-ccyy /A01-01-19tt /Od1
  1172.  
  1173. EXAMPLES:
  1174.  
  1175.      FDATE /Ff /Imm-dd-ccyy /A01-01-tttt
  1176.      FDATE /Ff /Imm-dd-yy   /A01-01-tt 
  1177.  
  1178.      rem report the 15th day of this month, this year
  1179.      FDATE /Ff /Imm-dd-ccyy /Att-15-tttt
  1180.  
  1181.      rem Show the first Monday in the second quarter of this year
  1182.      FDATE /Fw /Iccyymmdd /Atttt0401 /D2 /N1  /P"First Monday in QTR#2: "
  1183.  
  1184.      rem Show the last Friday on/before the 15th of this month.
  1185.      FDATE /Fw /Iccyymmdd /Atttttt15 /D6 /N-1 /P"Friday before the 15th: "
  1186.  
  1187.  
  1188. INPUT DATE FORMATS
  1189. ==================
  1190.  
  1191.  
  1192. ABSOLUTE DATE INPUT FORMATS
  1193. ===========================
  1194.  
  1195. day#           727198      "Absolute date": date expressed as number of
  1196.                            days since the beginning of the calendar.  "1"
  1197.                            for January 1, 0001, "2" for January 2, 0001,
  1198.                            etc.
  1199.  
  1200. minute#         33088       "Absolute minutes": time expressed as number
  1201.                             of minutes  since midnight, January 1, 1990.
  1202.  
  1203. CALENDAR DATE INPUT FORMATS
  1204. ===========================
  1205.  
  1206. FORMAT      EXAMPLES      DISCUSSION
  1207. ------      ---------     -----------------------------
  1208.  ccyymmdd    19922002
  1209.  
  1210.  
  1211. On the /I (input format) parm, the separator character of the following
  1212. input formats must be a dash.  This simply tells Fdate that the input
  1213. date will contain SOME separator character.  The separator character that
  1214. actually occurs in dates in the /A and /B parms is ignored, and may be
  1215. any non-numeric character: a slash "/", a dash "-", a dot ".", etc.
  1216.  
  1217. In specifications that begin with "mm-dd" or "dd-mm", leading zeros need
  1218. not be present in the "mm" and "dd" part of the date.
  1219.  
  1220. ccyy-mm-dd  1992-02-20    Leading zeros MUST be present, since the
  1221.             1992/02/20    date does not begin with dd-mm or mm-dd.    
  1222.             1992.02.20    
  1223.  
  1224.  
  1225. mm-dd-ccyy  02-20-1992    
  1226.             02/20/1992    The dash represents ANY non-numeric character.
  1227.  
  1228.              2-5-1992     Leading zeros need not be present.
  1229.              2/5/1992
  1230.  
  1231. mm-dd-yy    02-05-92      February 5, 1992.  See discussion of
  1232.              2/5/92       FDATE'S CENTURY ASSUMPTION ALGORITHM, below
  1233.  
  1234.                           ---------------------------------------
  1235.                           In the following formats, days
  1236.                           precede months  (European style)
  1237.                           ---------------------------------------
  1238.  
  1239. dd-mm-ccyy  05-02-1992 
  1240.             05/02/1992 
  1241.  
  1242.              5-2-1992     Leading zeros need not be present.
  1243.              5/2/1992
  1244.  
  1245. dd-mm-yy    05-02-92      February 5, 1992.  See discussion of
  1246.              5/2/92       FDATE'S CENTURY ASSUMPTION ALGORITHM, below
  1247.  
  1248. BUSINESS JULIAN DATE INPUT FORMATS
  1249. ==================================
  1250.  
  1251. These are formats for "business julian" dates: dates expressed as the
  1252. number of days from the beginning of the year, when January 1 is day 1.
  1253.  
  1254. EXAMPLES:
  1255.  
  1256.       date      BUSINESS JULIAN DATE
  1257.   -----------   --------------------
  1258.   Jan  5, 1992  92005
  1259.   Jan  5, 1993  93005
  1260.   Dec 31, 1993  93365  [Dec 31 is 365th day of year 1993]
  1261.   Dec 31, 1996  96366  [Dec 31 is 366th day, because 1996 is a leap year]
  1262.  
  1263. -----------------------------------------------------------------------
  1264. NOTE:   * JJJ can be 1 - 5 digits
  1265.         * may include a prefix of a plus or minus ( + or - ) sign
  1266. -----------------------------------------------------------------------
  1267.  
  1268. FORMAT      EXAMPLES      DISCUSSION
  1269. ------      ---------     -----------------------------
  1270. ccyyjjj     1992003       Third day of 1992, i.e. Jan 3, 1992
  1271.             19923         Third day of 1992
  1272.             tttt003       Third day of this year
  1273.             tttt3         Third day of this year
  1274.  
  1275.   yyjjj       92003       Third day of 1992
  1276.               923         Third day of 1992
  1277.               tt003       Third day of this year
  1278.               tt3         Third day of this year
  1279.               01003       Third day of 2001           See
  1280.                           FDATE'S CENTURY ASSUMPTION ALGORITHM, below
  1281.  
  1282. NOTE THAT FDATE WILL ACCEPT "JJJ" OF LESS THAN 1 & MORE THAN 366.
  1283. -----------------------------------------------------------------
  1284.  
  1285.   yyjjj       tt1000      the 1000th day from beginning of this year
  1286.               tt0         last day of last year
  1287.               tt-1        next-to-last day of last year
  1288.  
  1289. FDATE /Ff /Iccyyjjj /Od1 /A1992-1  produces... Monday December 30, 1991
  1290. FDATE /Ff /Iccyyjjj /Od1 /A19920   produces... Tuesday December 31, 1991
  1291. FDATE /Ff /Iccyyjjj /Od1 /A1992+1  produces... Wednesday January 1, 1992
  1292.  
  1293. FDATE /Ff /Iccyyjjj /Od1 /A1992366 produces... Thursday December 31, 1992
  1294. FDATE /Ff /Iccyyjjj /Od1 /A1992367 produces... Friday January 1, 1993
  1295.  
  1296. This feature allows limited date arithmetic with ordinary business
  1297. Julian days.  For example, 90 days from tt300 can be shown by:
  1298.  
  1299.                   FDATE /Ff /Iyyjjj /Att390
  1300.  
  1301. GETTING DATE/TIME A FILE WAS CREATED
  1302. ====================================
  1303.  
  1304. FORMAT      EXAMPLES      DISCUSSION
  1305. ------      ---------     -----------------------------
  1306. f           MYFILE.1      Input format F (file) tells Fdate that
  1307.                           /A and /B will specify filenames, and that
  1308.                           Fdate should pick up the input date and time
  1309.                           from the date/time stamp on a file.
  1310.  
  1311. Example: FDATE /Ff /If /Afdate.exe /P"FDATE.EXE last updated: " /Ofull
  1312.  
  1313.      Note that if you specify /If, then both /A and /B will be interpreted
  1314.      as filenames.
  1315.  
  1316.      Because the input format applies to both /A and /B parms, it is not
  1317.      possible to put a filename in /A and a date literal in /B, and then
  1318.      (say) use the "comp" or "dif" function to compare them.  You must
  1319.      first extract the file's date into an environment variable, and then
  1320.      compare that environment variable to the date literal.
  1321.  
  1322.           The only exception to this rule is the pseudodate "t" (i.e. /At
  1323.           or /Bt) which will pick up the current date and time from the
  1324.           system clock.  This feature will allow you, for example, to
  1325.           compare the date of a file to today's date (see EXAMPLES).
  1326.  
  1327.      A filename may (but need not) be fully qualified: i.e. "MYFILE.1" and
  1328.      "C:\DBASE\WORKDIR\MYFILE.1" are both acceptable.
  1329.  
  1330.      A filename may contain wildcards.  If it does, the date/time stamp
  1331.      will be retrieved from the first file that FDATE finds that meets the
  1332.      filespec.  Giving FDATE a filespec containing a wildcard is pretty
  1333.      useless, but FDATE will not reject it.
  1334.  
  1335. OUTPUT DATE FORMATS
  1336. ===================
  1337.  
  1338. FORMAT        EXAMPLES      COMMENTS
  1339. ------        ---------     -----------------------------
  1340. dd-mn3-yy     08-Feb-92     CompuServe-style date
  1341.   yy            93          2-digit year number
  1342. ccyy          1993          4-digit year number (includes century)
  1343. ccyymm        199302        useful for triggering monthly processing
  1344. ccyymmdd      19930208      useful for putting current date in filename
  1345.   yymmdd        930208      PKZIP's Japanese date format
  1346.     mmdd          0208
  1347.      mmddyy      020892    PKZIP's American date format
  1348.      mmddccyy   02081992 
  1349.       mm            02      2-digit month number
  1350.       zm             2      month number, no leading zeros
  1351.       dd            08      2-digit day-of-month number
  1352.       zd             8      day-of-month number, no leading zeros
  1353.  
  1354. In the following formats, months precede days (American style)
  1355. ------------------------------------------------------------------
  1356. mm/dd/ccyy    02/08/1993
  1357. mm-dd-ccyy    02-08-1993
  1358. mm.dd.ccyy    02.08.1993    British-style dates
  1359.  
  1360. zm/zd/ccyy     2/8/1993     no leading zeros in day or month
  1361. zm-zd-ccyy     2-8-1993     no leading zeros in day or month
  1362. zm.zd.ccyy     2.8.1993     British-style dates
  1363.  
  1364. mm/dd/yy      02/08/92
  1365. mm-dd-yy      02-08-92
  1366. mm.dd.yy      02.08.92      British-style dates
  1367.  
  1368. zm/zd/yy       2/8/92       no leading zeros in day or month
  1369. zm-zd-yy       2-8-92       no leading zeros in day or month
  1370. zm.zd.yy       2.8.92       no leading zeros in day or month
  1371.  
  1372.  
  1373. In the following formats, days precede months  (European style)
  1374. ------------------------------------------------------------------
  1375.  
  1376. ddmmccyy      02081993
  1377.    ddmmyy        020893PKZIP's European date format
  1378.  
  1379. dd/mm/ccyy    02/08/1993
  1380. dd-mm-ccyy    02-08-1993
  1381. dd.mm.ccyy    02.08.1993    British-style dates
  1382.  
  1383. zd/zm/ccyy     2/8/1993     no leading zeros in day or month
  1384. zd-zm-ccyy     2-8-1993     no leading zeros in day or month
  1385. zd.zm.ccyy     2.8.1993     British-style dates
  1386.  
  1387. dd/mm/yy      02/08/93
  1388. dd-mm-yy      02-08-93
  1389. dd.mm.yy      02.08.93      British-style dates
  1390.  
  1391. zd/zm/yy       2/8/93       no leading zeros in day or month
  1392. zd-zm-yy       2-8-93       no leading zeros in day or month
  1393. zd.zm.yy       2.8.93       British-style dates
  1394.  
  1395. DAY-OF-WEEK AND MONTH OUTPUT FORMATS
  1396. ====================================
  1397.  
  1398. dow#           5            Sunday=1, Monday=2 .... Saturday=7.
  1399.  
  1400. dow            Thursday     name of day of week
  1401.                jeudi        if /Lfr specified
  1402.                Donnerstag   if /Lgr specified
  1403.  
  1404. dow3           Thu          first 3 characters of name of day of week
  1405.                jeu          if /Lfr specified
  1406.                Don          if /Lgr specified
  1407.  
  1408. mn             February     name of month
  1409.                fevrier      if /Lfr specified
  1410.                Februar      if /Lgr specified
  1411.  
  1412. mn3            Feb          first 3 characters of name of month
  1413.                fev          if /Lfr specified
  1414.                Feb          if /Lgr specified
  1415.  
  1416.  
  1417.  
  1418. MISCELLANEOUS OUTPUT FORMATS
  1419. ============================
  1420.  
  1421. full      9:05 pm on Wednesday February 5, 1992
  1422.           9:05 pm, mercredi le 5 fevrier 1992  [/Lfr specified]
  1423.           9:05 pm, miércoles el 5 de febrero de 1992 [/Lsp specified]
  1424.           Mittwoch, 5. Februar 1992, 21:05     [/Lgr specified]
  1425.  
  1426. d1        Saturday, February 5, 1992
  1427.           samedi le 5 fevrier 1992      [/Lfr specified]
  1428.           Mittwoch, 5. Februar 1992     [/Lgr specified]
  1429.  
  1430. ddmn3yy   05Feb92
  1431.  
  1432. xxx       2CP  (...Dec 25, 1992)
  1433.           This format represents dates for the years 1990-2024 in 3
  1434.           characters of "extended hex" ("XX") notation.  For more on XX
  1435.           notation, see the discussion of the #2XX function.
  1436.  
  1437.           The first character is the XX representation of the number of
  1438.           years since 1990 (1990 = 0, 1991 = 1, etc.).  If you attempt to
  1439.           output a date outside of the 1990-2024 range in XXX format, Fdate
  1440.           will report an error (i.e. return "ERROR" and errorlevel of 1).
  1441.  
  1442.           The second and third characters contain the XX representation of
  1443.           the month-number and day-of-month-number, respectively.
  1444.  
  1445.           EXAMPLE: "1993 Feb  1"  is represented as  "321"
  1446.           EXAMPLE: "2000 Dec 25"  is represented as  "ACP".
  1447.  
  1448. -----------------------------------------------------------------------
  1449. NOTE that the following formats contain embedded spaces.  Consequently
  1450. they must be enclosed in double quotes. EXAMPLE: /O"mn zd, ccyy".
  1451. -----------------------------------------------------------------------
  1452. "zd mn ccyy"      5 February 1992
  1453. "zd mn, ccyy"     5 February, 1992
  1454. "zd. mn ccyy"     5. February 1992   [German-style date format]
  1455. "zd. mn3 ccyy"    5. Feb 1992        [German-style date format]
  1456. "mn3 dd ccyy"     Feb 05 1992
  1457. "mn3 dd, ccyy"    Feb 05, 1992
  1458. "mn zd, ccyy"     February 5, 1992
  1459.  
  1460.  
  1461.  
  1462. LEAP-YEAR FLAG OUTPUT FORMAT
  1463. ============================
  1464.  
  1465. LY              0     "1" if date occurs in a leapyear, otherwise "0".
  1466.  
  1467.                  365 + this number gives total number of days in the year.
  1468.                   28 + this number gives total number of days in February.
  1469.  
  1470.  
  1471.  
  1472.  
  1473. TIME OUTPUT FORMATS
  1474. ===================
  1475. See also: the section on the /T (parm /A time override) parameter.
  1476.  
  1477. t1            9:05 am
  1478.               9:05 pm
  1479.  
  1480. tdos          9:05:10:10a     format used in DOS's TIME command 
  1481.               9:05:10:10p
  1482.  
  1483. HH:MM        09:05      24-hour time, hours:minutes
  1484.              21:05
  1485. HHMM         0905
  1486.              2105
  1487.  
  1488. HH:MM:SS     21:05:30   24-hour time, hours:minutes:seconds
  1489. HHMMSS       210530
  1490.  
  1491. HH:MM:SS:CC  21:05:30:09   24-hour time, in
  1492. HHMMSSCC     21053009      hours:minutes:seconds:hundredths of seconds
  1493.  
  1494.  
  1495. BUSINESS JULIAN DATE OUTPUT FORMATS
  1496. ===================================
  1497.  
  1498. These are formats for "business julian" dates: dates expressed as the
  1499. number of days from the beginning of the year, when January 1 is day 1.
  1500.  
  1501. EXAMPLES:
  1502.  
  1503.       DATE      BUSINESS JULIAN DATE
  1504.   -----------   --------------------
  1505.   Jan  5, 1993  93005
  1506.   Dec 31, 1993  93365  [Dec 31 is 365th day of year 1993]
  1507.   Dec 31, 1996  96366  [Dec 31 is 366th day, because 1996 is a leap year]
  1508.  
  1509.  
  1510. FORMAT        EXAMPLES      DISCUSSION
  1511. ------        ---------     -----------------------------
  1512.  
  1513. ccyyjjj       1992027       Jan 27, 1992
  1514.   yyjjj         92027       "Business Julian" date expressed as number
  1515.     jjj           027       of days since January 1 of the same year.
  1516.     zzj            27       Note leading zero suppression in "zzj".
  1517.  
  1518.  
  1519. ABSOLUTE DATE/TIME OUTPUT FORMATS
  1520. =================================
  1521. See also: the section on the /T (parm /A time override) parameter.
  1522.  
  1523.  
  1524. month#          23927      "Absolute month": date expressed as number of
  1525.                            months since the beginning of the calendar. 
  1526.                            Returns "1" for any date in January, 0001, "2"
  1527.                            for any date in February, 0001, etc.
  1528.  
  1529. day#           727198      "Absolute date": date expressed as number of
  1530.                            days since the beginning of the calendar. 
  1531.                            Returns "1" for January 1, 0001, "2" for
  1532.                            January 2, 0001, etc.
  1533.  
  1534. minute#         33088       "Absolute minutes": time expressed as number
  1535.                             of minutes  since midnight, January 1, 1990.
  1536.  
  1537. second#        633088       "Absolute seconds": time expressed as number
  1538.                             of seconds  since midnight, January 1, 1990.
  1539.  
  1540.  
  1541. Running FDATE with /O parameter for an "absolute time" produces a
  1542. number based on the current time of day and the date in the /A parm.
  1543.  
  1544. If, on January 10, 1992 at 2 pm, you run FDATE this way:
  1545.        FDATE /Ff /Atoday /Ominute#
  1546. it will produce the absolute minute for January 10, 1992 at 2 pm.
  1547.  
  1548. If, on January 10, 1992 at 2 pm, you run FDATE this way:
  1549.        FDATE /Ff /A01-15-1992 /Imm-dd-ccyy  /Ominute#
  1550. it will produce the absolute minute for January 15, 1992 at 2 pm.
  1551.  
  1552.  
  1553. /T: TIME OVERRIDE PARAMETER
  1554. ===============================
  1555.  
  1556. You may override Fdate's use of the current time -- for the /A parameter
  1557. only -- by using the /T parameter.  The /T parameter specifies a time of
  1558. day in the 24-hour format hh:mm:ss (hours:minutes:seconds).  Leading zeros
  1559. in each of the three fields (hh, mm, ss) may be omitted.  The seconds field
  1560. may be omitted; if omitted, it defaults to "00".
  1561.  
  1562. Note that the /T parm overrides the time portion of the /A date, but it
  1563. does NOT override the time portion of the /B date.
  1564.  
  1565. If, on January 10, 1992 at 2 pm, you run FDATE this way:
  1566.        FDATE /Ff /A01-15-1992 /Imm-dd-ccyy  /Ominute#  /T5:12
  1567. it will produce the absolute minute for January 15, 1992 at 5:12 am.
  1568.  
  1569. The most frequent and important use of the /T parm is with the format
  1570. function (/Ff) to obtain the "absolute" minute of a specific date and time. 
  1571. Once we have the absolute minutes of two different date/times, we can
  1572. easily obtain the time between them (expressed in days, hours, and minutes)
  1573. by using Fdate's #dif, #idiv, and #mod functions.  (In the EXAMPLES
  1574. section, see the example that contains FORATIME.BAT.)
  1575.  
  1576. It is also possible to use /T in conjunction with the time compare function
  1577. (/Ftcomp).
  1578.  
  1579. @echo ON
  1580. cls
  1581. rem  Since both /A and /B default to the current date and time,
  1582. rem  and since /T parm overrides the time only for the /A parm ...
  1583.  
  1584. rem   ... during daytime hours, this will always return LT
  1585. Fdate /ftcomp /T00:00:00
  1586. rem   ... during daytime hours, this will always return GT
  1587. Fdate /ftcomp /T23:59:59
  1588.  
  1589.  
  1590. /J: JUSTIFYING OUTPUT
  1591. ==========================
  1592. Using the /J (justify) parameter it is possible to right, center, or left-
  1593. justify FDATE's output.  See the discussion of JUSTIFYING OUTPUT in the
  1594. section on string-handling functions.
  1595.  
  1596.  
  1597.  
  1598. HOW TO PUT FDATE OUTPUT INTO AN ENVIRONMENT VARIABLE
  1599. ====================================================
  1600.  
  1601.  
  1602. CALL A BATCH FILE
  1603. =================
  1604.  
  1605.   The most basic way to put FDATE's output into an environment variable,
  1606.   although not the most convenient, is to:
  1607.   *  use the /P (prefix string) feature to create a DOS "SET" statement,
  1608.   *  redirect the output to a batch file, and then
  1609.   *  CALL the batch file.  
  1610.  
  1611.   Since CALL first appeared in DOS 3.3, you will need DOS 3.3 or greater
  1612.   to use this technique.
  1613.  
  1614.        FDATE /Ff /Atoday /O"mn zd, ccyy" /P"@SET FDATE=" >JUNKTEMP.BAT
  1615.        call JUNKTEMP.BAT
  1616.        del  JUNKTEMP.BAT
  1617.  
  1618.  
  1619.  
  1620. USE AN ENVIRONMENT-MANIPULATION UTILITY
  1621. =======================================
  1622.  
  1623.   There are shareware and public domain utilities that are written
  1624.   specifically to manipulate environment variables, and do that job very
  1625.   well.  FDATE's output can be put into an environment variable by piping
  1626.   it to one of these utilities.  When piping FDATE output to a utility,
  1627.   you can prevent the output from being ECHOed to the screen by
  1628.   redirecting the output to NUL.
  1629.  
  1630.   Of these utilities, I can especially recommend Bob Stephan's GET
  1631.   (because it is very inexpensive and very powerful and flexible) and PC
  1632.   Magazine's STRINGS (free to ZiffNet members).  See the EXAMPLES section
  1633.   for examples of how to use STRINGS and GET to put FDATE's output into an
  1634.   environment variable.
  1635.  
  1636.      As of March 14, 1994, the current version of GET is 2.6.  On
  1637.      CompuServe, use IBMFF to look for GET25.ZIP (which contains version
  1638.      2.5 and the full documentation file) and GET26u.ZIP (the version 2.6
  1639.      update of GET, which contains version 2.6 of GET, but not the full
  1640.      documentation).  Look in CIS:IBMSYS, Library 1, or for GET.ZIP in
  1641.      ZNT:UTILFORUM, lib 16.  GET is also available from the Public Software
  1642.      Library in Houston.
  1643.  
  1644.      As of February 14, 1992, the current version of STRINGS is 1.3. On
  1645.      CompuServe, look for STRING.ZIP in the PC Magazine Utilities Lib of
  1646.      ZNT:UTILFORUM.  STRHYP.ZIP contains good hypertext documentation on
  1647.      STRINGS.
  1648.  
  1649. FDATE'S /V PARAMETER
  1650. ====================
  1651.  
  1652.   Manipulating the environment is an incredibly tricky business.  There
  1653.   are questions of the local versus master environment, the version of DOS
  1654.   you are running, and the environment under which you are running (DOS,
  1655.   Windows, QuarterDeck, Carousel).  In order to keep FDATE focussed on
  1656.   date-related issues, versions of Fdate prior to 6.1 did not attempt to
  1657.   put output directly into an environment variable.  Instead, FDATE's
  1658.   output was written to standard output, that is, it was displayed on the
  1659.   screen. Output could then be redirected to a batch file, or piped to a
  1660.   utility (such as STRINGS or GET), that would put the output into an
  1661.   environment variable.
  1662.  
  1663.   Starting with version 6.1, Fdate supports a /V (environment variable)
  1664.   parameter.  A user can use /V to tell Fdate to put its output directly
  1665.   into an environment variable in the "parent" environment.
  1666.  
  1667.   NOTE that due to the complexities of manipulating the environment, there
  1668.   may be circumstances where /V doesn't work.  These include running FDATE
  1669.   when you have shelled out to DOS from another program, have put the
  1670.   command processor in upper memory (UMB) (see below), are running under
  1671.   Carousel, etc.  In such cases, you may be able to use one of the more
  1672.   basic techniques described above.  For a list of environments in which
  1673.   the /V option has been reported as NOT working, see the next section.
  1674.  
  1675.  
  1676.  
  1677.   /Vevar tells Fdate to put output into an environmental variable whose
  1678.   name is "evar".  For example:
  1679.  
  1680.                 Fdate /Ff /Vdate1
  1681.  
  1682.   will set the environment variable DATE1 to the current date.  If you
  1683.   type SET at the DOS prompt, you should see something like:
  1684.  
  1685.                 DATE1=Friday February 14, 1992
  1686.  
  1687.   If you specify /V without an evar name, the evar name defaults to FDATE.
  1688.  
  1689.      Example :       Fdate /Ff /V
  1690.      produces:       FDATE=Friday February 14, 1992
  1691.  
  1692.   If you do not use /V, Fdate output is written to standard output, i.e.
  1693.   to the screen.
  1694.  
  1695. /V WHEN RUNNING UNDER MICROSOFT WINDOWS
  1696. =======================================
  1697.  
  1698. Starting with FDATE version 8.4 -- thanks to a Turbo Pascal routine from
  1699. the Turbo Professional library (see below) provided by Kim Kokkonen of
  1700. TurboPower Software -- FDATE's /V parameter works even in a Windows DOS
  1701. box, assuming you have enough environment space available.
  1702.  
  1703. The problem is that when you shell out to a DOS box under Windows, the size
  1704. of the DOS environment is normally limited to the amount actually in use by
  1705. DOS at the time when you first started Windows (rounded up to multiples of
  1706. 16).  In short, when you shell out to DOS under Windows, you have little or
  1707. no free environment space left. 
  1708.  
  1709. The trick to giving yourself a decent amount of environment space in a
  1710. Windows DOS box, is to edit SYSTEM.INI and put the following line in the
  1711. [NonWindowsApp] section:
  1712.  
  1713.   [NonWindowsApp]
  1714.   CommandEnvSize=1024
  1715.  
  1716. This tip is from Brian Livingston's "Windows 3.1 Secrets", p. 225. 
  1717. According to Livingston, "This command allocates 1,024 bytes of
  1718. conventional memory to the environment space of each DOS session you start.
  1719. (You can choose any value you want, but it should probably be a multiple of
  1720. 16 bytes...)"
  1721.  
  1722. It's a good idea to be generous here, because the default prompt for a
  1723. Windows DOS box (the one with the highlighted bar across the top of the
  1724. screen) consumes a lot more environment space than the simple "$p$g" of the
  1725. conventional DOS prompt.
  1726.  
  1727. An alternative technique, if you're running Windows 3.0 or earlier, is
  1728. always to start Windows from a batch file that contains the following line,
  1729. executed BEFORE you start Windows:
  1730.  
  1731.    SET DUMMY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  1732.  
  1733. This will reserve a chunk of environment space that will be copied into the
  1734. environment in the Windows DOS box.  Then, as one of the first statements
  1735. in any batch file that you run under Windows, put
  1736.  
  1737.    SET DUMMY=
  1738.  
  1739. This will free up the environment space used by all those "X"s.  
  1740.  
  1741. For a good treatment of running DOS apps under Windows, including a
  1742. discussion of the environment, I recommend Brian Livingston's WINDOWS 3.1
  1743. SECRETS, chapter 7.
  1744.  
  1745.  
  1746. /V WHEN RUNNING UNDER WINDOWS NT
  1747. =======================================
  1748.  
  1749. Early in 1996, reports began trickling in of users having difficulty with
  1750. Fdate's /V feature (setting the value of an environment variable) when
  1751. running under Windows NT.  To make a long story short, in many cases,
  1752. Fdate's /V feature doesn't work under Windows NT.  Unfortunately, this
  1753. situation cannot be corrected.  Microsoft has never made it easy to access
  1754. the environment programmatically, and the situation has become worse in
  1755. Windows 95 and Windows NT.  The situation has become so difficult that
  1756. TurboPower Software, which markets add-on utilities, has withdrawn support
  1757. for utilities that change environment variables. Since Fdate uses these
  1758. utiltities, it is virtually certain that I will ever be able to make
  1759. Fdate's /V feature work under NT, in cases where it does not now work. 
  1760.  
  1761. This does not mean, however, that Fdate can't be used with NT.  What it
  1762. means is that, when running Fdate under NT, we have to fall back on a more
  1763. basic method of setting an environment variable.  This involves creating a
  1764. temporary batch file that sets the variable, then running and deleting the
  1765. batch file.  It's primitive, but it works.
  1766.  
  1767. This technique is described elsewhere in this documentation, but I will
  1768. repeat it here for convenience's sake.
  1769.  
  1770. CALL A BATCH FILE
  1771. =================
  1772.  
  1773. The most basic way to put FDATE's output into an environment variable is
  1774. to:
  1775.  
  1776.   *  use the /P (prefix string) feature to create a DOS "SET" statement and
  1777.   *  redirect the output to a temporary batch file, and then
  1778.   *  CALL the batch file, and then  
  1779.   *  delete the batch file (clean up after the operation). 
  1780.  
  1781. EXAMPLE:
  1782.  
  1783.        FDATE /Ff /At /Occyymmdd /P"@SET FDATE=" >JUNKTEMP.BAT
  1784.        call JUNKTEMP.BAT
  1785.        del  JUNKTEMP.BAT
  1786.  
  1787. In this example, the result will be that the FDATE environment variable is
  1788. set to today's date, in ccyymmdd format.
  1789.  
  1790. Turbo Professional: "Highly Recommended"
  1791.  
  1792.   Thanks to a Turbo Pascal routine from the Turbo Professional library
  1793.   (provided by Kim Kokkonen of TurboPower Software)  FDATE's /V parameter
  1794.   works even in a Windows DOS box.
  1795.  
  1796.   If you do serious Turbo Pascal programming, you should have Turbo
  1797.   Professional or Object Professional library.  Turbo Professional is a
  1798.   library of about 600 routines to do all sorts of useful stuff in Turbo
  1799.   Pascal programs, including:
  1800.  
  1801.      CRT unit emulation, with many added features
  1802.     Popup windows, virtual screens, and pulldown menu systems.
  1803.     Full screen data entry with formatting and data validation.
  1804.     Complete mouse support, keyboard macros, runtime error recovery.
  1805.     A context sensitive popup help unit.
  1806.     Units for picking from lists of items, including filenames.
  1807.     Easy and reliable ways to make your program memory resident.
  1808.     Interrupt service routine handlers, extended & expanded memory access.
  1809.     BCD arithmetic, including transcendental functions & the Form routine
  1810.     Sorting and searching.
  1811.     Extensive string manipulation & strings longer than 255 characters.
  1812.     Arrays larger than 64K (in RAM, EMS, or paged to disk)
  1813.  
  1814. For more information, call TurboPower at 1-800-333-4160 (9-5 Mountain
  1815. time), send CompuServe mail to 76004,2611, or visit the CompuServe
  1816. TurboPower forum in PCVENB section 6.
  1817.  
  1818. /V WHEN USING 4DOS, NDOS, AND UMB
  1819. =================================
  1820.     --------------------------------------------------------------
  1821.     I have received the following report from Aran Spence about
  1822.     circumstances in which FDATE /V will not set a variable
  1823.     in the master environment.  This report leads me to believe
  1824.     that FDATE /V may also fail to work with MS-DOS if you put
  1825.     the command processor or the environment in Upper Memory.
  1826.                     Note, however, that this behavior has not been tested
  1827.                     with FDATE 8.4's new environment-handling routines.
  1828.     --------------------------------------------------------------
  1829. Steve,
  1830.  
  1831. There are options with 4DOS and NDOS to load the environment and part
  1832. of the command processor into upper memory blocks.  When one of these
  1833. options is used, FDATE /V can't find the environment and produces the
  1834. message:
  1835.  
  1836.    ERROR
  1837.    @echo ERROR: Master environment not found
  1838.    @pause
  1839.  
  1840. If you have a 4DOS.INI file, it has to contain these lines for FDATE /V
  1841. to work:
  1842.  
  1843.    UMBEnvironment = No
  1844.    UMBLoad = No
  1845.  
  1846. If you have NDOS, the SHELL statement in CONFIG.SYS cannot contain
  1847. any reference to UMB loading via /U (which puts NDOS.COM in UMB), nor
  1848. can it contain a statement of the form:
  1849.                 /E:xxxU
  1850. (which puts xxx bytes of the environment in UMB via the "U" parameter).
  1851.  
  1852. Also, NSTART.BTM or 4START.BTM cannot contain
  1853.          SET NDSHELL=/e+xxxU /U
  1854. in which both U's represent UMB loading of the command processor and the
  1855. environment during secondary shells.
  1856.  
  1857. FDATE'S ERROR HANDLING
  1858. ======================
  1859.  
  1860.    If FDATE detects an error:
  1861.  
  1862.      (1) it will return an errorlevel of 1 (rather than 0), and
  1863.      (2) its output will be 3 lines:
  1864.        * the word ERROR
  1865.        * a DOS batch-file ECHO statement that displays an error message
  1866.        * a DOS batch-file PAUSE statement
  1867.  
  1868.    If Fdate output is displayed directly, or redirected to NUL,
  1869.    you can detect an error by testing the errorlevel for a value of 1.
  1870.  
  1871.    If Fdate output is piped to an environment manipulation utility such
  1872.    as STRINGS or GET, the environment variable will be set to ERROR.
  1873.    Errorlevel will be set by STRINGS/GET, and will probably be 0.
  1874.    In such a case, the only way to detect an error is to test the
  1875.    environment variable for the value ERROR.
  1876.  
  1877.    If FDATE output is redirected to a batch file, which is then
  1878.    CALLed to set an environment variable, the batch file will:
  1879.      * set the environment variable to ERROR,
  1880.      * ECHO the error message, and
  1881.      * pause.
  1882.    You can detect an error by testing errorlevel for the value 1
  1883.    either before or after you CALL the batch file, or 
  1884.    by testing the environment variable for the
  1885.    value ERROR, AFTER you have CALLed the batch file.
  1886.  
  1887. ----------------------------------------------------------------------
  1888.  
  1889.  EXAMPLE:
  1890.    rem use FDATE to check validity of year in parm %1
  1891.    Fdate /Fv /Imm-dd-ccyy /ATT-TT-%1 > nul
  1892.    if errorlevel 1 echo Year parm [%1] is not valid.
  1893.    if errorlevel 1 goto endit
  1894.  
  1895.  EXAMPLE:
  1896.    rem use GET with FDATE, to put FDATE output into %year%
  1897.    Fdate /Ff /Imm-dd-ccyy /ATT-TT-%1 /Occyy | GET ZE /V%year% >nul
  1898.    if (%year%)==(ERROR) echo Year parm [%1] is not valid.
  1899.    if (%year%)==(ERROR) goto endit
  1900.  
  1901.  EXAMPLE:
  1902.    rem use a batch file with FDATE, to put FDATE output into %year%
  1903.    Fdate /Ff /Imm-dd-ccyy /ATT-TT-%1 /Occyy /P"@set year=">junktemp.bat
  1904.    call junktemp.bat
  1905.    del  junktemp.bat
  1906.    if errorlevel 1 echo Year parm [%1] is not valid.
  1907.    if errorlevel 1 goto endit
  1908.  
  1909. EXAMPLES OF HOW TO USE FDATE
  1910. ============================
  1911.  
  1912. :01 Display Fdate output on screen
  1913. :==================================================================
  1914. FDATE /Ff /At /Od1 /P"Today is "
  1915.  
  1916.  
  1917. :02 Redirect FDATE output to a file
  1918. :==================================================================
  1919. FDATE /Ff /At /Od1 /P"Today is " >FDATE.OUT
  1920.  
  1921.  
  1922. :03 Put FDATE output in an environment variable using a batch file
  1923. :==================================================================
  1924. FDATE /Ff /Atoday /O"mn zd, ccyy" /P"@SET DATE1=" >JUNKTEMP.BAT
  1925. call JUNKTEMP.BAT
  1926. del  JUNKTEMP.BAT
  1927.  
  1928.  
  1929. :04 Put FDATE output in an environment variable using /V parm
  1930. :==================================================================
  1931. FDATE /Ff /Atoday /O"mn zd, ccyy" /Vdate1
  1932.  
  1933.  
  1934. :05 Put FDATE output in an environment variable using STRINGS
  1935. :==================================================================
  1936. FDATE /Ff /Atoday /O"mn zd, ccyy" |STRINGS date1= ASK >NUL
  1937.  
  1938.  
  1939. :06 Put FDATE output in an environment variable using GET
  1940. :==================================================================
  1941. FDATE /Ff /Atoday /O"mn zd, ccyy" |GET ZE /Vdate1 >NUL
  1942.  
  1943.  
  1944. :07 Get user input
  1945. :==================================================================
  1946. @echo off
  1947. cls
  1948. echo Enter a date in mm-dd-ccyy format for validation
  1949.  
  1950. :: get user input
  1951. fdate /fget /vUserDate1
  1952.  
  1953. :: validate user input using /Fv (validate function)
  1954. fdate /fv /A%UserDate1% >nul
  1955. if errorlevel 1 echo Invalid date: %UserDate1%
  1956. if errorlevel 1 goto endit
  1957.  
  1958. :: put your batch file processing here ...
  1959. echo Processing date: %UserDate1%
  1960.  
  1961. :endit
  1962. :: cleanup
  1963. set UserDate1=
  1964.  
  1965.  
  1966. :08 Get a user menu selection
  1967. :==================================================================
  1968. @echo off
  1969. :start
  1970. cls
  1971. echo ===========================================================
  1972. echo             MAKE A MENU SELECTION
  1973. echo ===========================================================
  1974. echo   A   DIR *.*
  1975. echo   B   DIR *.BAT
  1976. echo.
  1977. echo Press ESC to exit
  1978. echo.
  1979. echo ===========================================================
  1980. FDATE /FgetK /Q"Press letter of your choice> " /KABx /V
  1981.  
  1982. if (%FDATE%)==(A) goto Choice_%FDATE%
  1983. if (%FDATE%)==(B) goto Choice_%FDATE%
  1984. if (%FDATE%)==(x) goto endit
  1985. echo Program logic error.   Invalid choice [%FDATE%]
  1986. pause
  1987. goto Start
  1988.  
  1989. :CHOICE_A
  1990.  cls
  1991.  echo Processing choice %FDATE% ...
  1992.  DIR *.* /W /P
  1993.  pause
  1994.  goto Start
  1995.  
  1996. :CHOICE_B
  1997.  echo Processing choice %FDATE% ...
  1998.  DIR *.BAT /W /P
  1999.  pause
  2000.  goto Start
  2001.  
  2002. :endit
  2003. set choice=
  2004. cls
  2005.  
  2006.  
  2007. :09 Change a date from one format into another
  2008. :==================================================================
  2009. :: change date from mm-dd-yy format to ccyymmdd format
  2010. FDATE /Ff /Imm-dd-yy /A05-08-92 /Occyymmdd
  2011.  
  2012.  
  2013.  
  2014. :10 Find the difference in days between two dates
  2015. :==================================================================
  2016. FDATE /Fdif /Imm-dd-ccyy /A%date1% /B%date2% /vdiff
  2017. echo The difference is %diff% days.
  2018.  
  2019.  
  2020. :11 Find the elapsed days/hours/minutes between two date/times.
  2021. :===================================================================
  2022. This batch file was developed in cooperation with Walter Ledge, a sysop for
  2023. CompuServe's CRFORUM.  In addition to being a good example of how to use
  2024. Fdate's /T parm and "#idiv" function, it should be useful for other
  2025. CompuServe sysops who need to submit the same reports that Walt does. 
  2026. Here's Walt's message that started the whole thing.
  2027.  
  2028.   As an assistant sysop on the CRFORUM, I have to submit reports to CIS on
  2029.   the number of messages that are posted on our forum in terms of time per
  2030.   1,000 messages -- i.e., say, I know that 1,000 messages were posted
  2031.   between the hours of 17:05 on July 5 and 3:03 on July 7.  I need to know
  2032.   how many hours and minutes it took for those 1000 messages to be posted. 
  2033.   So I would like some way to use FDATE to calculate the difference
  2034.   between those two times (which, of course, include the dates).
  2035.  
  2036. FORATIM2.BAT is an improvement of the original FORATIME.BAT batch file. 
  2037. FORATIM2.BAT uses the /Fget function, which first appeared in Fdate 8.3, to
  2038. get user input from the terminal, rather than requiring all parameters to
  2039. be entered at the command line as FORATIME.BAT did. 
  2040.  
  2041. @echo off
  2042. cls
  2043. :: ------------------------------------------------------
  2044. :: FORATIM2.BAT batch file
  2045. ::
  2046. :: FUNCTION
  2047. ::    Calculate the elapsed time (in days and minutes)
  2048. ::    between some "begin" date/time and some "end" date/time
  2049. ::
  2050. :: ------------------------------------------------------
  2051. ECHO --------------------------------------------------------------
  2052. ECHO     Calculate elapsed time between two date/times
  2053. ECHO --------------------------------------------------------------
  2054.  
  2055. :BegDate
  2056. Fdate /Fget /VBEGdate /Q"Enter BEGIN DATE (mm-dd-ccyy): "
  2057. if (%BegDate%)==() goto Cleanup
  2058.  
  2059. :BegTime
  2060. Fdate /Fget /VBEGtime /Q"Enter BEGIN TIME (hh:mm).....: "
  2061. if (%BegTime%)==() goto Cleanup
  2062.  
  2063. :: validate date & time
  2064. fdate /fv /A%BEGdate% /T%BEGtime% >nul
  2065. if errorlevel 1 echo Invalid date/time
  2066. if errorlevel 1 goto BegDate
  2067.  
  2068. :: get absolute minute of start date/time.
  2069. fdate /ff /ominute# /A%BEGdate% /T%BEGtime% /VABStime1
  2070. if errorlevel 1 goto BegTime
  2071. fdate /ff /ofull    /A%BEGdate% /T%BEGtime% /Vfull1
  2072. ::
  2073. echo.
  2074. :EndDate
  2075. Fdate /Fget /VENDdate /Q"Enter END.. DATE (mm-dd-ccyy): "
  2076. if (%EndDate%)==() goto Cleanup
  2077.  
  2078. :EndTime
  2079. Fdate /Fget /VENDtime /Q"Enter END.. TIME (hh:mm).....: "
  2080. if (%EndTime%)==() goto Cleanup
  2081.  
  2082. :: validate date & time
  2083. fdate /fv /A%ENDdate% /T%ENDtime% >nul
  2084. if errorlevel 1 echo Invalid date/time
  2085. if errorlevel 1 goto EndDate
  2086.  
  2087. :: get absolute minute of end date/time.
  2088. fdate /ff /ominute# /A%ENDdate% /T%ENDtime% /VABStime2
  2089. if errorlevel 1 goto EndTime
  2090. fdate /ff /ofull    /A%ENDdate% /T%ENDtime% /Vfull2
  2091.  
  2092. echo.
  2093. ECHO Calculating elapsed time...
  2094. :: calculate the difference between ABStime1 and ABStime2
  2095. fdate /f#dif  /A%ABStime1% /B%ABStime2% /VMinutes
  2096.  
  2097. :: calculate the number of hours in it took
  2098. fdate /f#Idiv  /A%minutes% /B60  /VHours
  2099.  
  2100. :: calculate the number of extra minutes it took
  2101. fdate /f#mod   /A%minutes% /B60  /VMins
  2102.  
  2103. echo.
  2104. echo   Between %full1%
  2105. echo       and %full2%
  2106. echo.
  2107. echo   Elapsed time was:
  2108. echo           %hours% hours and %mins% minutes
  2109.  
  2110. fdate /f#Idiv /A%minutes% /B1440 /Vday1
  2111. fdate /f#mod  /A%minutes% /B1440 /Vmin1
  2112. fdate /f#Idiv /A%min1%    /B60   /Vhour1
  2113. fdate /f#mod  /A%min1%    /B60   /Vmin2
  2114. echo   or
  2115. echo         %day1% day(s) %hour1% hour(s) and %min2% minute(s).
  2116. echo.
  2117. echo.
  2118. ::
  2119. :cleanup
  2120. set ENDdate=
  2121. set BEGdate=
  2122. set BEGtime=
  2123. set ENDtime=
  2124. set full1=
  2125. set full2=
  2126. set minutes=
  2127. set ABStime1=
  2128. set ABStime2=
  2129. set day1=
  2130. set hour1=
  2131. set min1=
  2132. set min2=
  2133. set mins=
  2134. set hours=
  2135. :endit
  2136. :13 Find the elapsed years/months/days between two dates.
  2137. :===================================================================
  2138. @echo off
  2139. :: illustrate Fdate's Month# output format
  2140. cls
  2141. echo --------------------------------------------------------------
  2142. echo    YMD_DIF.BAT Calculate elapsed time between two dates
  2143. echo --------------------------------------------------------------
  2144.  
  2145. :: --------------------------------------------------------------
  2146. :D1
  2147. Fdate /Fget /VD1 /Q"Enter date #1 (mm-dd-ccyy), or ENTER to quit: "
  2148. if (%D1%)==() goto Cleanup
  2149.  
  2150. :: validate date
  2151. Fdate /Fv /A%D1%       >nul
  2152. if errorlevel 1 echo Invalid date
  2153. if errorlevel 1 goto D1
  2154.  
  2155. :: translate date into various formats, including absolute month
  2156. Fdate /Ff /oMonth# /A%D1% /VAbsMonth1
  2157. Fdate /Ff /oday#   /A%D1% /VAbsDay1
  2158. Fdate /Ff /A%D1%   /VFull1
  2159. Fdate /Ff /odd     /A%D1% /VDd1
  2160.  
  2161. :: --------------------------------------------------------------
  2162. :D2
  2163. Fdate /Fget /VD2 /Q"Enter date #2 (mm-dd-ccyy), or ENTER to quit: "
  2164. echo.
  2165. if (%D2%)==() goto Cleanup
  2166.  
  2167. :: validate date
  2168. Fdate /Fv /A%D2% >nul
  2169. if errorlevel 1 echo Invalid date
  2170. if errorlevel 1 goto D2
  2171.  
  2172. :: translate date
  2173. Fdate /Ff /oMonth# /A%D2% /VAbsMonth2
  2174. Fdate /Ff /oday#   /A%D2% /VAbsDay2
  2175. Fdate /Ff /A%D2%   /VFull2
  2176. Fdate /Ff /odd     /A%D2% /VDd2
  2177.  
  2178. :: --------------------------------------------------------------
  2179. :: verify that D2 is later than D1
  2180. Fdate /Fcomp /A%D2% /B%D1% /v
  2181. if (%Fdate%)==(GT) goto EndIf1
  2182.    echo     D2 must be later than D1.        Please try again.
  2183.    echo.
  2184.    goto D1
  2185. :EndIf1
  2186.  
  2187. :: verify that D2 is in a later month than D1
  2188. Fdate /F#comp /A%AbsMonth2% /B%Absmonth1% /v
  2189. if (%Fdate%)==(GT) goto EndIf2
  2190.    :: they are in the same month
  2191.    Fdate /Fdif /A%D1% /B%D2% /P"Difference is " /S" days."
  2192.    echo.
  2193.    goto Cleanup
  2194. :EndIf2
  2195.  
  2196. :: --------------------------------------------------------------
  2197. :: get difference in months
  2198. Fdate /F#dif /A%AbsMonth2% /B%Absmonth1% /vMonthsDif
  2199.  
  2200. :: compare days of month
  2201. Fdate /F#comp /A%Dd2% /B%Dd1% /v
  2202. if not (%Fdate%)==(LT) goto EndIf3
  2203.    :: Dd2 is less than Dd1 ... subtract 1 from (add -1 to) MonthsDif
  2204.    Fdate /F#add  /A%MonthsDif% /B-1 /VMonthsDif
  2205. :EndIf3
  2206.  
  2207.  
  2208. :: do month arithmetic, to get a date (D3) that is
  2209. :: less than 1 month prior to D2
  2210. Fdate /Fm /A%D1% /N%MonthsDif% /Omm-dd-ccyy /VD3
  2211.  
  2212. :: find difference in days between D3 & D2
  2213. Fdate /Fdif /A%D3% /B%D2% /Vdaysdif
  2214.  
  2215. :: --------------------------------------------------------------
  2216. echo Between %Full1% & %Full2% ...
  2217. echo                 %MonthsDif% month(s) %DaysDif% day(s)
  2218.  
  2219. :: calculate the number of years, by dividing MonthsDif by 12
  2220. Fdate /F#Idiv  /A%Monthsdif% /B12  /VYearsDif
  2221.  
  2222. :: calculate the number of extra months
  2223. Fdate /F#mod   /A%MonthsDif% /B12  /VMonthsDif
  2224.  
  2225. echo  or   %YearsDif% year(s) %MonthsDif% month(s) %DaysDif% day(s)
  2226.  
  2227. :: --------------------------------------------------------------
  2228. :cleanup
  2229. echo.
  2230. echo.
  2231. set D1=
  2232. set D2=
  2233. set D3=
  2234. set AbsMonth1=
  2235. set AbsMonth2=
  2236. set AbsDay1=
  2237. set AbsDay2=
  2238. set Full1=
  2239. set Full2=
  2240. set Dd1=
  2241. set Dd2=
  2242. set YearsDif=
  2243. set MonthsDif=
  2244. set DaysDif=
  2245. set Fdate=
  2246. :endit
  2247.  
  2248.  
  2249. :14 Determine how long it took a program to run
  2250. :==================================================================
  2251.  
  2252. @echo off
  2253. cls
  2254. ECHO ─────────────────────────────────────────────────────────────────────
  2255. ECHO       DETERMINE HOW LONG IT TOOK A PROGRAM TO RUN
  2256. ECHO           The demo will run for 1 - 60 seconds.
  2257. ECHO ──────────────────────────────────────────────────────────────────────
  2258. PAUSE
  2259. cls
  2260. :: Get the time (in julian seconds) that the program began running
  2261. set PgmName=DemoFake_Pgm
  2262. FDATE /Ff /Osecond# /VBegS
  2263. FDATE /Ff /Ohh:mm:ss /P"%PgmName% execution begins at "
  2264.  
  2265. :: ───────── DEMO BEGIN ──────────────────────────────────────────
  2266. :: For purposes of this demo, we simulate execution of a
  2267. :: program by looping until the minute changes.  In your real
  2268. :: batch file, you would put your program statements here.
  2269. :: ───────────────────────────────────────────────────────────────
  2270. FDATE /Ff /Ohhmm /vBegM
  2271. :BegLoop
  2272.    rem  Since this is a demo, give the folks something to watch
  2273.    FDATE /Ff    /Osecond# /vSeconds
  2274.    FDATE /F#dif /A%Seconds% /B%BegS% /P".... elapsed time: " /S" seconds."
  2275.    FDATE /Ff  /Ohhmm     /vNowM
  2276. if (%NowM%)==(%BegM%) goto BegLoop
  2277. set BegM=
  2278. set NowM=
  2279. :: ───────── DEMO END   ──────────────────────────────────────────
  2280.  
  2281. :: Get the time (in julian seconds) that the program finished
  2282. FDATE /Ff  /Osecond# /vEndS
  2283. :: tell the user the time that the program finished
  2284. FDATE /Ff  /Ohh:mm:ss /P"%PgmName% execution ends at "
  2285.  
  2286. :: calculate run time (difference between start time and end time)
  2287. FDATE /F#dif /A%EndS% /B%BegS% /vSeconds
  2288. :: convert  seconds to  minutes + seconds  format
  2289. FDATE /F#idiv /A%Seconds% /B60 /vMinutes
  2290. FDATE /F#mod  /A%Seconds% /B60 /vMinSecs
  2291.  
  2292. :: tell the user how long the program took to run
  2293. echo Runtime: %Seconds% seconds (%Minutes% minutes %MinSecs% seconds)
  2294. :: cleanup            
  2295. set PgmName=
  2296. set BegS=
  2297. set EndS=
  2298. set Seconds=
  2299. set Minutes=
  2300. set MinSecs=
  2301.  
  2302. :15 Find years when a given date fell on a given day of the week
  2303. :==================================================================
  2304. [WHATDAY.BAT  This program has virtually no data validation, but if you are
  2305. careful to enter valid input data, it does the job.] 
  2306.  
  2307.  @echo off
  2308.  :: ----------------------------------------------------------------
  2309.  :: This program calculates the years (within a specified range) that a
  2310.  :: certain day of a certain month fell on a certain day of the week.
  2311.  ::
  2312.  :: Note that we calculate and test both the day of the week and the
  2313.  :: month.  This is because, for example, "February 29" of
  2314.  :: a non-leapyear (an invalid date)
  2315.  :: will be converted to the valid date of March 1.
  2316.  :: So we want to be sure that in a given year, February 29 not only
  2317.  :: occurred on the weekday in question, but also actually
  2318.  :: occurred in February.
  2319.  :: ----------------------------------------------------------------
  2320.  cls
  2321.  echo This program calculates the years (within a specified range) that a
  2322.  echo certain day of a certain month fell on a certain day of the week.
  2323.  echo.
  2324.  echo Please enter the day of the week that you want to search for.
  2325.  echo   1 = Sunday
  2326.  echo   2 = Monday
  2327.  echo   3 = Tuesday
  2328.  echo   4 = Wednesday
  2329.  echo   5 = Thursday
  2330.  echo   6 = Friday
  2331.  echo   7 = Saturday
  2332.  echo.
  2333.  fdate /fgetk /K1234567x /Q"Please press a number, or ESC to exit > " /vdow
  2334.  if (%Dow%)==(x) goto endit
  2335.  if (%Dow%)==(1) set DowName=Sunday
  2336.  if (%Dow%)==(2) set DowName=Monday
  2337.  if (%Dow%)==(3) set DowName=Tuesday
  2338.  if (%Dow%)==(4) set DowName=Wednesday
  2339.  if (%Dow%)==(5) set DowName=Thursday
  2340.  if (%Dow%)==(6) set DowName=Friday
  2341.  if (%Dow%)==(7) set DowName=Saturday
  2342.  echo You chose day of the week: %dowName%
  2343.  pause
  2344.  
  2345.  fdate /fget /Q"Please enter first year in year range > " /vBegYr
  2346.  fdate /fget /Q"Please enter last_ year in year range > " /vEndYr
  2347.  fdate /fget /Q"Please enter month number (1-12) > " /vMonNum
  2348.  fdate /fget /Q"Please enter day__ number (1-31) > " /vDayNum
  2349.  
  2350.  set Yr=%BegYr%
  2351.  fdate /fsubstr /a-2 /q00%MonNum% /vMonNum
  2352.  
  2353.  rem >whatday.txt
  2354.  cls
  2355.  echo Looking for %MonNum%/%DayNum% on %DowName%
  2356.  echo between %BegYr% and %EndYr%
  2357.  echo ----------------------------------------------
  2358.  echo Looking for %MonNum%/%DayNum% on %DowName% >>whatday.txt
  2359.  echo between %BegYr% and %EndYr% >>whatday.txt
  2360.  echo ---------------------------------------------- >>whatday.txt
  2361.  
  2362.  :LoopTop
  2363.    fdate /fsubstr /a-4 /q0000%yr% /vyr
  2364.    echo Testing %yr%
  2365.    fdate /ff /Idd-mm-ccyy /A%DayNum%-%MonNum%-%Yr% /v
  2366.    fdate /ff /Idd-mm-ccyy /A%DayNum%-%MonNum%-%Yr% /odow# /vdow#
  2367.    fdate /ff /Idd-mm-ccyy /A%DayNum%-%MonNum%-%Yr% /omm   /vmm
  2368.  
  2369.    if (%Dow#%)==(%Dow%) if (%MonNum%)==(%mm%) echo %fdate%
  2370.    if (%Dow#%)==(%Dow%) if (%MonNum%)==(%mm%) echo %fdate% >>Whatday.txt
  2371.  
  2372.    fdate /f#add  /A%yr% /B1 /vYr
  2373.    fdate /f#comp /A%yr% /B%EndYr% /v
  2374.    if (%fdate%)==(GT) goto LoopEnd
  2375.    goto LoopTop
  2376.  :LoopEnd
  2377.  
  2378.  cls
  2379.  type whatday.txt
  2380.  echo.
  2381.  echo This data has been written to file: Whatday.txt
  2382.  echo.
  2383.  :endit
  2384.  set Yr=
  2385.  set BegYr=
  2386.  set EndYr=
  2387.  set mm=
  2388.  set Dow=
  2389.  set Dow#=
  2390.  set DowName=
  2391.  set fdate=
  2392.  set MonNum=
  2393.  set DayNum=
  2394.  
  2395. :16 Find calendar date corresponding to a "business Julian" date
  2396. :==================================================================
  2397. rem business julian date is 1992:045.  Note input format CCYYjjj
  2398. FDATE /Ff /A1992045  /Iccyyjjj  /Od1
  2399.  
  2400. rem You don't need to left-zero-fill the day
  2401. FDATE /Ff /A199245  /Iccyyjjj  /Od1
  2402.  
  2403. rem You can assume the century, if you specify the YYjjj input format
  2404. FDATE /Ff /A9245  /Iyyjjj  /Od1
  2405.  
  2406. :17 Set your PC's date to a business julian date
  2407. :==================================================================
  2408. @echo off
  2409. goto enddoc
  2410. ---------------------------------------------------------------------
  2411. This batch file was created by Aran Spence [CIS: 70162,3044].  Its
  2412. function is to emulate the DOS DATE command, but allow the user to set
  2413. the date using a business julian date format (yyjjj) instead of
  2414. mm-dd-yy.
  2415.  
  2416. Note the format is YYjjj. This is the BUSINESS julian date: a date
  2417. expressed as the number of days from the beginning of the year,
  2418. when January 1 is day 1.
  2419.  
  2420.            date      BUSINESS julian date
  2421.        -----------   --------------------
  2422.        Jan 5, 1992       92005
  2423.        Jan 5, 1993       93005
  2424.        Dec 31, 1993      93365  [Dec 31 is 365th day of year 1993]
  2425.  
  2426. As Aran originally wrote it, the user-prompt was virtually identical to
  2427. that of the DATE command.  I have modified his original version, so it
  2428. now looks less like the DATE command but displays a bit more
  2429. information, and so it can operate from the command line.
  2430.  
  2431. If the user enters a business julian date as a command-line
  2432. parameter, JDATE resets the date to that julian date.
  2433.              EXAMPLE:  JDATE 92005
  2434. If there is no input parameter, /fget is used to prompt the user for a
  2435. date.
  2436.  
  2437. Note that the user must enter both of the year digits (yy),
  2438. but may enter an abbreviated set of day digits (jjj).  That is,
  2439. for julian day 92005, the user is permitted to enter 925.
  2440.  
  2441. One handy use for JDATE is simply to find out what the current
  2442. business julian date is.
  2443. ---------------------------------------------------------------------
  2444. :enddoc
  2445.  
  2446. SET NewJD=%1
  2447. if not (%NewJD%)==() goto GotDate
  2448.  
  2449. :ShowDate
  2450. Fdate /Ff /Od1    /P"Current Gregorian date: "
  2451. Fdate /Ff /Oyyjjj /P"'Business Julian' date: "
  2452.  
  2453. :GetDate
  2454. GET S "Enter new date (yyddd): " /VNewJD /L
  2455. if (%NewJD%)==() goto endit
  2456.  
  2457. :GotDate
  2458. Fdate /Ff /A%NewJD% /Omm-dd-yy /Iyyjjj /VNewGD
  2459. if errorlevel 1 echo Invalid date "%NewJD%"
  2460. if errorlevel 1 goto GetDate
  2461.  
  2462. ::   reset the date
  2463. DATE %NewGD%
  2464.  
  2465. echo SYSTEM DATE HAS BEEN RESET
  2466. Fdate /Ff /Od1    /P"Current Gregorian date: "
  2467. Fdate /Ff /Oyyjjj /P"'Business Julian' date: "
  2468.  
  2469. :endit
  2470. SET NewJD=
  2471. SET NewGD=
  2472. echo.
  2473.  
  2474. :18 Determine if parm %1 contains a valid date
  2475. :==================================================================
  2476. COMMENT
  2477.   Note that we throw away the FDATE output by redirecting it to NUL.  All
  2478.   we really want here is the errorlevel, which tells us whether or not the
  2479.   string in %1 is a valid year.
  2480.  
  2481. Fdate /Fv /Imm-dd-ccyy /A%1  >nul
  2482. if errorlevel 1 echo Parm 1 was not a valid date: %1
  2483. if errorlevel 1 goto endit
  2484.  
  2485. ::
  2486. :: Put the body of your batch file here.
  2487. ::
  2488.  
  2489. :endit
  2490.  
  2491.  
  2492.  
  2493. :19 "Roll your own" date format 
  2494. :==================================================================
  2495. @echo of
  2496. cls
  2497. :: EXAMPLE A: create a date in the format of the DOS "date" command
  2498. :: format, followed by the DOS "time" command format
  2499.  
  2500. :: get the three-character day-of-week name
  2501. Fdate /Ff /Odow3 /Vx
  2502.  
  2503. :: add mm-dd-ccyy to it
  2504. Fdate /Ff /Omm-dd-ccyy /p"%x% " /Vx
  2505.  
  2506. :: add the DOS "time" format (new output format in Fdate 8.6)
  2507. Fdate /Ff /Otdos       /p"%x% " /Vx
  2508. echo Date/time = %x%
  2509.  
  2510. :: EXAMPLE B: create a date in custom-made format: yymn3dd
  2511. Fdate /Ff /Oyy          /Vx
  2512. Fdate /Ff /Omn3 /P"%x%" /Vx
  2513. Fdate /Ff /Odd  /P"%x%" /Vx
  2514. echo Today is %x%
  2515.  
  2516. :: EXAMPLE C: create a date with day and month date-parts right justified
  2517. ::            and padded with spaces, such as " 1- 1-1995" for Jan 1, 1995
  2518. fdate /ff /ozd   /j"R 2" /vzd
  2519. fdate /ff /ozm   /j"R 2" /vzm
  2520. fdate /ff /occyy /p"%zd%-%zm%-"  /v
  2521. echo Today is [%fdate%]
  2522.  
  2523. :20 Find the 4th Thursday in November (Thanksgiving)
  2524. :==================================================================
  2525. Fdate /Fw /D5 /N4 /A11-01-%year% /Imm-dd-ccyy /Od1 /P"Thanksgiving: "
  2526.  
  2527.  
  2528. :22 On a date, show what anniversary it is for some event
  2529. :==================================================================
  2530. See HOLIDAYS.BAT demo batch file
  2531.  
  2532.  
  2533. :23 Show a list of holidays in a given year
  2534. :==================================================================
  2535. See HOLIDAYS.BAT demo batch file
  2536.  
  2537.  
  2538. :24 Show a list of Federal holidays in a given year
  2539. :==================================================================
  2540. See HOLIFEDS.BAT demo batch file
  2541.  
  2542. :25 Determine if a year is valid, and evenly divisible by 4
  2543. :==================================================================
  2544.  
  2545. @echo off
  2546. cls
  2547. echo FUNCTION: Accept a year parm (CCYY) as parameter 1.  Determine if
  2548. echo the year is an election or inauguration year in the United States.
  2549. echo ===================================================================
  2550.  
  2551. rem verify %1 is a valid year
  2552. Fdate /Fv /Imm-dd-ccyy /A01-01-%1 >nul
  2553. if errorlevel 1 echo Year parm [%1] is not valid.
  2554. if errorlevel 1 goto endit
  2555.  
  2556. Fdate /Ff /Imm-dd-ccyy /A01-01-%1 /p"@set year=">junktemp.bat
  2557. call junktemp.bat
  2558.  
  2559. Fdate /F#mod /A%1 /B4 /p"@set mod=">junktemp.bat
  2560. call junktemp.bat
  2561. if (%mod%)==(0) echo %1 is an American presidential election year.
  2562. if (%mod%)==(1) echo %1 is an American presidential inauguration year.
  2563. for %%v in (2 3) do if (%mod%)==(%%v) echo %1 is not an election year.
  2564. for %%v in (2 3) do if (%mod%)==(%%v) echo %1 is not an inauguration year.
  2565.  
  2566. set mod=
  2567. :endit
  2568. if exist junktemp.bat del  junktemp.bat
  2569.  
  2570.  
  2571.  
  2572.  
  2573. :30 Compare a file's date to today's date
  2574. :==================================================================
  2575. rem Compare today's date to the date on the filename in %1
  2576. Fdate /Fcomp /At /If /B%1 /Vcomp
  2577. if (%comp%)==(EQ) echo %1 was created or updated today
  2578. set comp=
  2579.  
  2580.  
  2581. :31 Compare two files' date/time using COMPARE-FUNCTION ERRORLEVELS
  2582. :==================================================================
  2583. COMMENT
  2584. There are many ways to check errorlevels.  This example shows 
  2585. several of them.
  2586.  
  2587. @echo off
  2588. cls
  2589. SET F1=FDATE.BAT
  2590. SET F2=FDATE.EXE
  2591. fdate /FTcomp /If /A%f1%  /B%F2% /P"%f1% is " /S" %f2%"
  2592.  
  2593. if errorlevel 101 if not errorlevel 103 echo %f1% is LT/EQ %f2%
  2594. if errorlevel 102                       echo %f1% is GT/EQ %f2%
  2595.  
  2596. if errorlevel 101 if not errorlevel 102 echo %f1% is older than %f2%
  2597. if errorlevel 102 if not errorlevel 103 echo %f1% is same age as %f2%
  2598. if errorlevel 103 if not errorlevel 104 echo %f1% is younger than %f2%
  2599.  
  2600. if errorlevel 101 if not errorlevel 103 echo %f1% at least as old as %f2%
  2601. if errorlevel 102                       echo %f1% is no older than %f2%
  2602.  
  2603. if errorlevel 101 if not errorlevel 102 echo errorlevel is 101
  2604. if errorlevel 102 if not errorlevel 103 echo errorlevel is 102
  2605. if errorlevel 103 if not errorlevel 104 echo errorlevel is 103
  2606. SET F1=
  2607. SET F2=
  2608. :endit
  2609.  
  2610.  
  2611.  
  2612. :32 Display a list of all files that were created/updated today. 
  2613. :==================================================================
  2614. @echo off
  2615. if (%1)==(SUBROUTINE) goto %2
  2616.  
  2617. CLS
  2618. ECHO FILES MEETING FILESPEC [%1] THAT WERE CREATED OR UPDATED TODAY
  2619. REM  The batch file calls itself: Its own name is in parm %0
  2620. for %%v in (%1) do  CALL %0 SUBROUTINE CHECKFILE %%v
  2621.  
  2622. set comp=
  2623. goto endit
  2624.  
  2625. :CHECKFILE
  2626. shift
  2627. shift
  2628.  
  2629. rem Compare today's date to the date on the %1 file
  2630.  Fdate /Fcomp /If /A%1 /Vcomp
  2631.  
  2632. rem echo the filename if the file was created/updated today
  2633. if (%comp%)==(EQ) echo %1
  2634. :endit
  2635. :33 MIN_MATH.BAT -- "time arithmetic" in minutes
  2636. :===================================================================
  2637. @echo off
  2638. cls
  2639. :: MIN_MATH.BAT -- Add or subtract time, in minutes, from the present
  2640.  
  2641. :: Get number of minutes from parm1, if present.  otherwise, use 4 minutes
  2642. :: not that Minutes can contain a negative number, if we wish to subtract
  2643. :: some minutes
  2644.  
  2645. set Minutes=4
  2646. if not (%1)==() set Minutes=%1
  2647.  
  2648. :: get the absolute minute NOW 
  2649. :: Alternatively, you can use the /A parm and the /T parm
  2650. :: to start from the date and time of your choice.
  2651. fdate /ff /ominute# /vAbsMin
  2652.  
  2653. :: add a certain number of minutes
  2654. fdate /f#add /a%AbsMin% /b%Minutes% /VNewMin
  2655.  
  2656. :: display the results
  2657. fdate /ff /iminute# /ofull /a%AbsMin% /p"We add %Minutes% minutes to "
  2658. fdate /ff /iminute# /ofull /a%NewMin% /p"producing: "
  2659.  
  2660. set Minutes=
  2661. set AbsMin=
  2662. set NewMin=
  2663.  
  2664. echo.
  2665. :endit
  2666. :34 TIME_SET.BAT -- "time arithmetic" -- set TIME
  2667. :===================================================================
  2668. @echo off
  2669. :: advance the time by 3 hours, then set it back again
  2670. set Minutes=180
  2671. cls
  2672.  
  2673. FDATE /FF /Ofull /P"It is now "
  2674.  
  2675. :: get the absolute minutes now
  2676. fdate /ff /ominute# /vAbsMin
  2677.  
  2678. :: add a certain number of minutes
  2679. fdate /f#add /a%AbsMin% /b%Minutes% /VNewMin
  2680.  
  2681. :: reset the time and date
  2682. fdate /ff /a%NewMin% /Iminute# /omm-dd-yy /vdate
  2683. fdate /ff /a%NewMin% /Iminute# /ohh:mm    /vtime
  2684. time %time%
  2685. date %date%
  2686.  
  2687. echo %Minutes% minutes added...
  2688. FDATE /FF /Ofull /P"It is now "
  2689.  
  2690. ECHO.
  2691. ECHO DOING SOME WORK ...
  2692. ECHO.
  2693.  
  2694. FDATE /FF /Ofull /P"It is now "
  2695.  
  2696. :: get the absolute minutes now
  2697. fdate /ff /ominute# /vAbsMin
  2698.  
  2699. :: subtract (add negative) a certain number of minutes
  2700. fdate /f#add /a%AbsMin% /b-%Minutes% /VNewMin
  2701.  
  2702. :: reset the time and date
  2703. fdate /ff /a%NewMin% /Iminute# /omm-dd-yy /vdate
  2704. fdate /ff /a%NewMin% /Iminute# /ohh:mm    /vtime
  2705. time %time%
  2706. date %date%
  2707.  
  2708. echo %Minutes% minutes subtracted ...
  2709. FDATE /FF /Ofull /P"It is now "
  2710.  
  2711. set Minutes=
  2712. set AbsMin=
  2713. set NewMin=
  2714. set time=
  2715. set date=
  2716. echo.
  2717. :endit
  2718.  
  2719. :41 Delete files more than X days old (use a batch-file subroutine)
  2720. :==================================================================
  2721. See the COMMENTARY that follows the text of the batch file.
  2722.  
  2723.  
  2724. @echo off
  2725. if (%1)==(SUBROUTINE) goto %2
  2726. cls
  2727.  
  2728. goto EndDoc
  2729. ----------------------------------------------------------------------
  2730. OLDFILES.BAT
  2731. This batch file shows how to do work on files that are older than
  2732. %NumDays%.  The PROCESS! subroutine can be modified to do any kind of
  2733. work you want.
  2734. ----------------------------------------------------------------------
  2735. :EndDoc
  2736.  
  2737. :: set the number of days in the past.   if this value is not passed
  2738. :: in via parameter %1, it defaults to 3 days
  2739. set NumDays=%1
  2740. if (%NumDays%)==() SET NumDays=3
  2741.  
  2742.  
  2743. echo ------------------------------------------------------------------
  2744. echo           PROCESSING FILES CREATED MORE THAN %NumDays% DAYS AGO
  2745. echo ------------------------------------------------------------------
  2746. for %%v in (*.*) do  CALL %0 SUBROUTINE PROCESS! %%v
  2747. echo ------------------------------------------------------------------
  2748. echo           END OF PROCESSING
  2749. echo ------------------------------------------------------------------
  2750.  
  2751. :: CLEANUP
  2752. set NumDays=
  2753. set DaysOld=
  2754. set Comparison=
  2755. GOTO ENDIT
  2756.  
  2757. :
  2758. :PROCESS!
  2759. shift
  2760. shift
  2761.  
  2762. :: get difference in days between filedate and today.
  2763. :: Note that /B parm (which is omitted) defaults to today's date.
  2764. fdate /fdif   /A%1        /IF          /VDaysOld
  2765.  
  2766. :: compare DaysOld to NumDays
  2767. fdate /f#comp /A%DaysOld% /B%NumDays%  /Vcomparison
  2768.  
  2769. :: the following line will DISPLAY THE NAME AND AGE OF
  2770. :: any file for which %DaysOld% is greater than %NumDays%
  2771. :: --------------------------------------------------------------
  2772. if (%comparison%)==(GT) echo %1 is %DaysOld% days old.
  2773.  
  2774. :: EXAMPLE (to activate this routine, remove the REM from column 1)
  2775. :: the following line will COPY TO AN ARCHIVE SUBDIRECTORY
  2776. :: any file for which %DaysOld% is greater than %NumDays%
  2777. :: -----------------------------------------------
  2778. REM if (%comparison%)==(GT) COPY %1 C:\ARCHIVE\*.*
  2779.  
  2780. :: EXAMPLE (to activate this routine, remove the REM from column 1)
  2781. :: the following line will DELETE
  2782. :: any file for which %DaysOld% is greater than %NumDays%
  2783. :: -----------------------------------------------
  2784. REM if (%comparison%)==(GT) DEL %1
  2785.  
  2786. :: fall through to endit
  2787.  
  2788. :endit
  2789.  
  2790.  ===============================================================
  2791.                         COMMENTARY BEGIN
  2792.  ===============================================================
  2793.  This batch file uses a crude, but effective, technique for giving a
  2794.  batch file the ability to call subroutines.  If you've never seen
  2795.  something like this before, it is sort of mind-blowing.  Here's some
  2796.  commentary on the more important lines involved in the technique.
  2797.  ===============================================================
  2798.  
  2799.  if (%1)==(SUBROUTINE) goto %2
  2800.  
  2801.     COMMENTARY:
  2802.     If the first parameter, %1, is "SUBROUTINE", then the batch file
  2803.     recognizes that it is being called for the purpose of executing
  2804.     one of its own subroutines.  In such a case, it does a GOTO to the
  2805.     start of the requested subroutine.  That is, it goes to the label
  2806.     whose name is in the second parameter.
  2807.  
  2808.     Explicitly specifying the name of the desired subroutine permits
  2809.     permits us to have multiple subroutines in the batch file,
  2810.     each with its own name.  (As it happens, in this batch file
  2811.     we have only one subroutine, named "PROCESS!")
  2812.  
  2813.     If the first parameter is not "SUBROUTINE", then we fall through
  2814.     and begin executing the main routine of the batch file.  In such a
  2815.     case, the first parameter (%1) may contain a number, indicating
  2816.     the number of days to use in determining which files to delete.
  2817.  
  2818.     Note that this technique will make the batch file malfunction
  2819.     if the user himself ever executes the batch file from the
  2820.     DOS command line with the word "SUBROUTINE" as the first
  2821.     parameter, the word "PROCESS!" as the second parameter, and a
  2822.     third parameter that is missing or not a valid filename.
  2823.     This is so unlikely, however, that it is reasonable
  2824.     to assume that it will never happen.
  2825.  
  2826.  ===============================================================
  2827.  
  2828.  for %%v in (*.*) do  CALL %0 SUBROUTINE PROCESS! %%v
  2829.  
  2830.     COMMENTARY:
  2831.     In a batch file, %0 contains the name by which the batch file was
  2832.     invoked.  We use this fact to allow a batch file to call itself,
  2833.     regardless of what name the user has given to it.
  2834.  
  2835.     The first parameter passed, when the batch file calls
  2836.     itself, is the string "SUBROUTINE".  This string allows the batch
  2837.     file to recognize when it is being called for the purpose of
  2838.     executing one of its own subroutines.
  2839.  
  2840.     The second parameter is the name of the subroutine that we want
  2841.     to call: in this case, "PROCESS!".
  2842.  
  2843.     The third parameter is what we would normally think of as the first
  2844.     parameter to the subroutine.  In this case, when the
  2845.     FOR statement is executed, and the substitution for %%v takes
  2846.     place, it will contain the name of the file to be processed.
  2847.     Note that we could, if we wished, pass additional parameters to
  2848.     the subroutine.  Note also that we can control the files that
  2849.     we process.  We do so via the filemask in the FOR statement.
  2850.     It we used, for example, "*.EXE", then we would process only
  2851.     executable files.
  2852.  
  2853.  ===============================================================
  2854.  
  2855.  GOTO ENDIT
  2856.  
  2857.    COMMENTARY:
  2858.    When the mainline of the batch file is finished executing, we
  2859.    goto the end of the batch file.  We MUST do this GOTO in order
  2860.    to avoid falling through into, and starting to execute, the first
  2861.    of the batch file's subroutines.
  2862.  
  2863.  ===============================================================
  2864.  
  2865.  :PROCESS!
  2866.  shift
  2867.  shift
  2868.  
  2869.    COMMENTARY:
  2870.    Note that when the batch file is called as a subroutine, and the
  2871.    batch file goes to the PROCESS! label, the values of the parms are:
  2872.            %0 = [the name of the batch file]
  2873.            %1 = SUBROUTINE
  2874.            %2 = PROCESS!
  2875.            %3 = [name of the file to be processed]
  2876.  
  2877.     We shift all the parameters to the left twice, to move the
  2878.     parameter(s) into what we think of as the
  2879.     proper places for parameters to the subroutine.
  2880.  
  2881.     After the first SHIFT command:
  2882.            %0 = SUBROUTINE
  2883.            %1 = PROCESS!
  2884.            %2 = [name of the file to be processed]
  2885.  
  2886.     After the second SHIFT command:
  2887.            %0 = PROCESS!
  2888.            %1 = [name of the file to be processed]
  2889.  
  2890.     Now %1 contains what we think of as the proper parameter(s)
  2891.     to the subroutine.  In this case, %1 contains the filename that
  2892.     we want the subroutine to process.
  2893.  
  2894.     At the end of every subroutine, there should be a GOTO ENDIT,
  2895.     which causes the batch file to go to its own end, and then
  2896.     end and return control to the statement in the program which called
  2897.     it.  (This is, of course, the CALL statement embedded in the
  2898.     FOR statement.)
  2899.  
  2900.     We can optimize the batch file a little by omitting the "goto endit"
  2901.     at the end of the last subroutine.  Instead, we simply allow the
  2902.     last subroutine to fall through to the end of the batch file.
  2903.  
  2904.  ===============================================================
  2905.                          COMMENTARY END
  2906.  ===============================================================
  2907.  
  2908. :42 Get date to tell PKZIP to compress files older than 30 days
  2909. :======================================================================
  2910. PKZIP (a popular file-compression utility) can be used to compress and
  2911. archive files that are older/younger than a given date.  To run PKZIP on
  2912. files that are, for example, older than 30 days, we need the date that was
  2913. 30 days before today's date.  To get it, we use Fdate to subtract 30 days
  2914. from today's date, and put that date out in PKZIP's "American" format
  2915. (MMDDYY). (Fdate also supports PKZIP's Japanese and European formats.)
  2916.  
  2917. To compress all files that were created before a date 30 days ago:
  2918.  
  2919.      Fdate /Fsub /N30 /Ommddyy /VArchiveDate
  2920.      pkzip test.zip -T%ArchiveDate%
  2921.  
  2922. For more information, see PKZIP's MANUAL.DOC file.
  2923.  
  2924. :43 Loop through an array of environment variables
  2925. :======================================================================
  2926. @echo off
  2927. cls
  2928. SET pct=%%%
  2929. SET prefix=Address
  2930.  
  2931. ECHO LOADING AN ARRAY
  2932. SET subscript=1
  2933. SET %prefix%.%subscript%=Stephen Ferg
  2934. SET subscript=2
  2935. SET %prefix%.%subscript%=5113 N. 8th Road
  2936. SET subscript=3
  2937. SET %prefix%.%subscript%=Arlington, VA 22205
  2938.  
  2939. ECHO UNLOADING AND DISPLAYING THE ARRAY
  2940. SET subscript=1
  2941. :LoopTop
  2942. REM do while subscript less than/equal 3
  2943. if %subscript%==4 goto LoopEnd
  2944.  
  2945.    REM put value of subscripted variable into tempvar
  2946.    ECHO SET tempvar=%pct%%prefix%.%subscript%%pct%>JUNKTEMP.BAT
  2947.    CALL JUNKTEMP.BAT
  2948.  
  2949.    REM display value of subscripted variable
  2950.    ECHO %prefix%.%subscript% is: %tempvar%
  2951.  
  2952.    REM delete subscripted variable
  2953.    SET %prefix%.%subscript%=
  2954.  
  2955.    REM increment the loop variable
  2956.    Fdate /F#add /A%subscript% /B1 /Vsubscript
  2957.    goto LoopTop
  2958. :LoopEnd
  2959.  
  2960. SET pct=
  2961. SET tempvar=
  2962. SET prefix=
  2963. SET subscript=
  2964. DEL JUNKTEMP.BAT
  2965.  
  2966. :44 Do something on the last day (or last Friday) of the month
  2967. :==================================================================
  2968. COMMENT
  2969. We often need batch files that do some special task on the last day of the
  2970. month: run a backup job, display a reminder message, etc.  This example
  2971. batch file, LASTDAY.BAT, simply displays a message -- you can modify it to
  2972. do whatever it is that YOU want to do.
  2973.  
  2974. If you plan to run LASTDAY.BAT at work, and you work Monday through Friday,
  2975. then checking for the last day of the month would be a poor strategy --
  2976. after you leave work on a Friday, the last day of the month might occur on
  2977. the following Saturday or Sunday.   So I've included a check to see if the
  2978. Friday is the last working day of the month.  If you don't want that
  2979. functionality, deleting the lines between the first and last occurrence of
  2980. the string "EndCheck" will remove it.
  2981. =======================================================================
  2982.  @echo off
  2983.  REM ---------------------------------------------------------------
  2984.  REM check to see if today is the last day of the month
  2985.  REM ---------------------------------------------------------------
  2986.  REM get today's month
  2987.  fdate /ff        /omm /vmmtoday
  2988.  
  2989.  REM get tomorrow's month
  2990.  fdate /fadd /n1 /omm  /vmmtomorrow
  2991.  
  2992.  REM if tomorrow occurs in a different month,
  2993.  REM then today is the last day of this month
  2994.  if not (%mmtoday%)==(%mmtomorrow%) echo LAST DAY OF THE MONTH
  2995.  if not (%mmtoday%)==(%mmtomorrow%) goto EndCheck
  2996.  
  2997.  REM -------------------------------------------------------------
  2998.  REM check to see if today is the last Friday of the month
  2999.  REM -------------------------------------------------------------
  3000.  rem get today's day of the week, to see if it is Friday
  3001.  fdate /ff /odow3 /vdow3
  3002.  if not (%dow3%)==(Fri) goto EndCheck
  3003.  
  3004.  REM today is Friday.  Get next Monday's month
  3005.  fdate /fadd /n3 /omm  /vmmMonday
  3006.  
  3007.  REM if next Monday occurs in a different month,
  3008.  REM then today is the last Friday of this month
  3009.  if not (%mmtoday%)==(%mmMonday%) echo LAST WORKING DAY OF THE MONTH
  3010.  
  3011.  :EndCheck
  3012.  
  3013.  REM cleanup
  3014.  set dow3=
  3015.  set mmtoday=
  3016.  set mmtomorrow=
  3017.  set mmMonday=
  3018.  
  3019. :45 Get information about the month prior to the current month
  3020. :==================================================================
  3021. COMMENT
  3022. When running a monthly backup job at the beginning of the month, one often
  3023. needs to identify the previous month, or the last day of the previous
  3024. month.  Here's how to use Fdate to obtain that sort of information. 
  3025. Basically, we subtract one day from the first day of the current month,
  3026. giving us the last day of the previous month.
  3027. =======================================================================
  3028. @echo off
  3029. cls
  3030. : The simplest way to get information about last month is to subtract
  3031. : 1 day from the first day of this month ...
  3032.  
  3033. fdate /fsub /n1 /att-01-tttt /omm   /p"Last month was.................: "
  3034. fdate /fsub /n1 /att-01-tttt /occyy /p"Last month occurred in the year: "
  3035. fdate /fsub /n1 /att-01-tttt /odd   /p"The last day of last month was : "
  3036. fdate /fsub /n1 /att-01-tttt /od1   /p"The last day of last month was : "
  3037.  
  3038.  
  3039.  
  3040. :46 Show the last Monday (or any other weekday) in this month
  3041. :==================================================================
  3042. @echo off
  3043. cls
  3044. :: Use monthly arithmetic to get first day of next month
  3045. fdate /fm /n1 /att-01-tttt /omm-dd-ccyy   /v
  3046.  
  3047. :: get the preceding Monday, i.e. the last Monday in this month
  3048. fdate /fw /d2 /n-1 /x /a%fdate%
  3049.  
  3050. :47 Show the last Monday in the month, for a series of months
  3051. :==================================================================
  3052. @echo off
  3053. cls
  3054. :: initialize constants
  3055. set StartDate=01-01-1996
  3056. set MONTHS=15
  3057.  
  3058. echo Show the last Mondays in the month,
  3059. echo for the %months% months starting %StartDate%
  3060. echo ==============================================================
  3061.  
  3062. set COUNT=1
  3063. :LOOPTOP
  3064.   :: compare COUNT to MONTHS, exit loop if COUNT exceeds MONTHS
  3065.   FDATE /F#comp /A%COUNT% /B%MONTHS% /vCOMP
  3066.   if (%COMP%)==(GT) goto ENDLOOP
  3067.  
  3068.   :: Use monthly arithmetic to get first day of next month
  3069.   FDATE /Fm /N%COUNT% /A%StartDate% /Omm-dd-ccyy   /Vfdate
  3070.  
  3071.   :: get the preceding Monday (/D2) -- the last Monday in this month
  3072.   FDATE /Fw /D2 /N-1 /X /A%fdate% /P"%count% "
  3073.  
  3074.   :: increment COUNT
  3075.   FDATE /F#add /A%COUNT% /B1 /Vcount
  3076.   GOTO LOOPTOP
  3077. :ENDLOOP
  3078. echo.
  3079.  
  3080. :endit
  3081. set StartDate=
  3082. set MONTHS=
  3083. set COUNT=
  3084. set COMP=
  3085. set FDATE=
  3086.  
  3087. :50 Represent a date in 3 bytes of "extended hex" notation
  3088. :==================================================================
  3089.  
  3090. rem produce today's date as 3 bytes
  3091. fdate /ff /oxxx 
  3092.  
  3093. rem produce yesterday's date in xxx format
  3094. fdate /fsub /N1 /oxxx
  3095.  
  3096.  
  3097.  
  3098.  
  3099. :51 Represent a date in a short (4-byte) format (technique #1)
  3100. :==================================================================
  3101. COMMENT
  3102. A common use of Fdate is to format today's date and use it to rename a file
  3103. (typically a log file of some sort).  You may wish to store the date
  3104. information in as few characters as possible, in order to maximize the
  3105. number of other characters in the filename that you can use to store other
  3106. information.
  3107.  
  3108. In this example, and the next one, I illustrate two ways to store a date in
  3109. 4 bytes.
  3110.  
  3111.  
  3112. The simplest way is to represent today's date as a 4-digit number.
  3113. To do this, we first pick a base date:  I'll use January 1, 1990.
  3114. Then it is a simple matter to calculate the number of days between today
  3115. and the base date:
  3116.  
  3117.            FDATE /Fdif /at /b01-01-1990 
  3118.  
  3119. Starting in 1993, this will always generate a 4-digit number, and will
  3120. continue to do so for 20 years, until approximately the year 2003.  Dates
  3121. before 1993 may produce 1-, 2-, or 3-digit numbers, and dates after 2003
  3122. will begin to produce 5-digit numbers.  But this technique will work quite
  3123. nicely for most ordinary purposes for the next 20 years.  
  3124.  
  3125. If you're still using DOS in the year 2003, then in 2003 you can switch to
  3126. using January 1, 2000 as your base date and function quite nicely for the
  3127. next 20 years after that.
  3128.  
  3129. :52 Represent a date in a short (4-byte) format (technique #2)
  3130. :==================================================================
  3131. @echo off
  3132. cls
  3133. goto end-doc
  3134. ------------------------------------------------------------------
  3135. This batch file shows how to use Fdate's #2XX function to
  3136. obtain and represent today's date in 4 characters, YYMD, where:
  3137.  
  3138.   YY is the year (e.g. "93" for 1993)
  3139.    M is the month in extended hexadecimal (XX) notation
  3140.    D is the day-of-the-month in extended hexadecimal (XX) notation
  3141.  
  3142. You can also use Fdate's "XXX" output format to represent dates between
  3143. 1990 and 2024 in 3 bytes of extended hex notation.
  3144. ------------------------------------------------------------------
  3145. :end-doc
  3146.  
  3147. REM OBTAIN 1-CHARACTER REPRESENTATION FOR THE MONTH
  3148. Fdate /ff    /Omm   /Vmm
  3149. Fdate /f#2xx /A%mm% /Vmm
  3150. echo XX representation of this month's number      is %mm%
  3151.  
  3152. REM OBTAIN 1-CHARACTER REPRESENTATION FOR THE DAY
  3153. Fdate /ff    /Odd   /Vdd
  3154. Fdate /f#2xx /A%dd% /Vdd
  3155. echo XX representation of today's day of the month is %dd%
  3156.  
  3157. REM CONCATENATE THEM TO THE 2-CHARACTER REPRESENTATION FOR THE YEAR
  3158. Fdate /Ff /Oyy /S%mm%%dd% /Vdate
  3159. echo XX representation of today's full date        is %date%
  3160.  
  3161. REM CLEANUP
  3162. set mm=
  3163. set dd=
  3164. set date=
  3165. :endit
  3166.  
  3167.  
  3168.  
  3169. :53 Convert numbers to "extended hex" (XX) format
  3170. :==================================================================
  3171. @echo off
  3172. cls
  3173. SET decnum=0
  3174. :top
  3175.    if (%decnum%)==(37) goto endit
  3176.    fdate /f#2xx /A%decnum% /P"XX representation of %decnum% is "
  3177.    fdate /f#add /A%decnum% /b1 /Vdecnum
  3178. goto top
  3179.  
  3180. :endit
  3181.  
  3182. :54 Customize Fdate for a language of your choice
  3183. :==================================================================
  3184. @echo off
  3185. cls
  3186. goto end-doc
  3187. ------------------------------------------------------------------
  3188. You can use Fdate with a customized batch file to obtain the names of
  3189. the days of the week and the months in a language of your choice.  Or
  3190. you could use it to obtain names in uppercase, or the first 5
  3191. characters of the names (rather than the first three), or some other
  3192. customized formatting of your choice.)
  3193.  
  3194. I've invented a language called Fergian, which has its own names for
  3195. the days of the week, and the months.  In the following examples, I
  3196. invoke FERGIAN.BAT to make the translation.  The text of FERGIAN.BAT,
  3197. which does the real work here, is given in the next example.
  3198. ------------------------------------------------------------------
  3199. :end-doc
  3200.  
  3201. fdate /ff /omm /v
  3202. call Fergian mm- result %Fdate%
  3203. echo Month  is          %result%
  3204.  
  3205. fdate /ff  /omm /v
  3206. call Fergian mm3 result %Fdate%
  3207. echo Month3 is          %result%
  3208.  
  3209. fdate /ff /odow#  /v
  3210. call Fergian dw- result %Fdate%
  3211. echo Day of week  is    %result%
  3212.  
  3213. fdate /ff /odow#  /v
  3214. call Fergian dw3 result %Fdate%
  3215. echo Day of week3 is    %result%
  3216.  
  3217. REM cleanup
  3218. set Fdate=
  3219. set result=
  3220.  
  3221. :55 Fergian.BAT (used in the previous example)
  3222. :==================================================================
  3223. @echo off
  3224. set  %2=
  3225. goto %1
  3226.  
  3227. goto end-doc
  3228. --------------------------------------------------------------------
  3229. This batch file converts a month number, or day of the week number,
  3230. to a name in the FERGIAN language.
  3231. You can copy this batch file and customize it, to make it translate
  3232. into some other language of your choice.
  3233.  
  3234. This batch file expects the following parameters:
  3235.  
  3236. %1 contains the type of number you want to convert:
  3237.    MM- if you want the entire name of the month
  3238.    MM3 if you want the first 3 letters of the name of the month
  3239.  
  3240.    DW- if you want the entire name of the day of the week
  3241.    DW3 if you want the first 3 letters of the name of the day of the week
  3242.  
  3243. %2 contains the name of the environment variable that you
  3244.    want to use to hold the result
  3245.  
  3246. %3 contains the number that you want to convert
  3247. --------------------------------------------------------------------
  3248. :end-doc
  3249.  
  3250. :MM-
  3251. if (%3)==(01) set %2=Jaded
  3252. if (%3)==(02) set %2=Febrile
  3253. if (%3)==(03) set %2=Martial
  3254. if (%3)==(04) set %2=Abigail
  3255. if (%3)==(05) set %2=Maybelene
  3256. if (%3)==(06) set %2=Junkaroo
  3257. if (%3)==(07) set %2=Julia
  3258. if (%3)==(08) set %2=Augmentation
  3259. if (%3)==(09) set %2=Separation
  3260. if (%3)==(10) set %2=Ostentation
  3261. if (%3)==(11) set %2=Novelty
  3262. if (%3)==(12) set %2=Decadence
  3263. goto endit
  3264.  
  3265. :
  3266. :MM3
  3267. if (%3)==(01) set %2=Jad
  3268. if (%3)==(02) set %2=Feb
  3269. if (%3)==(03) set %2=Mar
  3270. if (%3)==(04) set %2=Abi
  3271. if (%3)==(05) set %2=May
  3272. if (%3)==(06) set %2=Jun
  3273. if (%3)==(07) set %2=Jul
  3274. if (%3)==(08) set %2=Aug
  3275. if (%3)==(09) set %2=Sep
  3276. if (%3)==(10) set %2=Ost
  3277. if (%3)==(11) set %2=Nov
  3278. if (%3)==(12) set %2=Dec
  3279. goto endit
  3280.  
  3281. :DW-
  3282. if (%3)==(1) set %2=SunDay
  3283. if (%3)==(2) set %2=MoonDay
  3284. if (%3)==(3) set %2=TwickasDay
  3285. if (%3)==(4) set %2=WodensDay
  3286. if (%3)==(5) set %2=ThorsDay
  3287. if (%3)==(6) set %2=FreyasDay
  3288. if (%3)==(7) set %2=SaturnDay
  3289. goto endit
  3290.  
  3291.  
  3292. :DW3
  3293. if (%3)==(1) set %2=Sun
  3294. if (%3)==(2) set %2=Moo
  3295. if (%3)==(3) set %2=Twi
  3296. if (%3)==(4) set %2=Wod
  3297. if (%3)==(5) set %2=Tho
  3298. if (%3)==(6) set %2=Fre
  3299. if (%3)==(7) set %2=Sat
  3300. goto endit
  3301.  
  3302. :endit
  3303.  
  3304. :61 DO-ONCE: Run apps when booting for the first time of the day
  3305. :===============================================================
  3306. COMMENT
  3307.   Put this code in AUTOEXEC.BAT.  Note that this batch code requires DOS
  3308.   3.3+, since it uses CALL.
  3309.  
  3310. if not exist C:\LASTRUN.BAT goto RunNow
  3311.  
  3312. rem call LASTRUN.BAT, which will set an environment variable, %LASTRUN%,
  3313. rem that will contain the date when this batch file was last run.
  3314. rem ------------------------------------------------------------------
  3315. call C:\LASTRUN.BAT
  3316.  
  3317. rem compare the date in %LASTRUN% to today's date
  3318. rem ------------------------------------------------------------------
  3319. Fdate /Fcomp /At /B%LastRun% /Vcomp
  3320.  
  3321. : Today's date may be less than %LASTRUN% if you reset the system clock
  3322. IF (%COMP%)==(LT) goto NoRun
  3323. : If %LASTRUN% was the same as today's date,
  3324. :   then this batch file has already been run once today
  3325. IF (%COMP%)==(EQ) goto NoRun
  3326.  
  3327. : Daily processing hasn't been run today. Run it.
  3328. : Here, you should put the batch-file body --
  3329. : the code to run the applications that you want to run once per day
  3330. :
  3331.  
  3332. : ------------------------------------------------------------------
  3333. : Save today's date in a new version of LastRun.BAT.  Note that
  3334. : this code will be executed only if daily processing runs to
  3335. : completion without hanging the machine or aborting the batch file.
  3336. : ------------------------------------------------------------------
  3337. Fdate /Ff /Omm-dd-ccyy /At /P"@set LastRun=">LastRun.BAT
  3338.  
  3339. :NoRun
  3340. set LastRun=
  3341. set COMP=
  3342.  
  3343. :62 Run specific software, depending on the day of the week
  3344. :==================================================================
  3345. COMMENT
  3346. This is a very common use for Fdate.  I use it to load an alarm-clock TSR
  3347. (Terminate and Stay Resident, "memory resident", program) that beeps at me
  3348. (at different times on different days of the week) to remind me that it is
  3349. time to attend a meeting that is regularly scheduled for that day of the
  3350. week.
  3351.  
  3352. Note that stuff for a given day of the week will be executed every time you
  3353. boot up on that day of the week.  If you want stuff (e.g. a backup job) to
  3354. be run only once (the first time you boot up) on a given day of the week,
  3355. then:
  3356.  
  3357. (1)  copy the code from DO-ONCE (the previous example) into your
  3358.      AUTOEXEC.BAT file, then
  3359.  
  3360. (2)  copy this code into the body of the DO-ONCE code that you copied into
  3361.      AUTOEXEC.BAT in the last step.  If you do that, then this code will be
  3362.      run only once per day, even if you boot up multiple times per day.
  3363.  
  3364. Remember that if you are executing other batch files from a batch file, 
  3365. you should invoke them with a CALL statement:
  3366.               CALL batchfilename parm1 parm2 ...
  3367. so control will return to the calling batch file when execution of the
  3368. called batch file is complete.      
  3369.  
  3370. Note that the string comparison is case sensitive.
  3371. ==================================================================
  3372.  
  3373. :: get 3-character day-of-week name and put it in DOW e-var
  3374. FDATE /ff /oDOW3 /vDOW
  3375.  
  3376. if (%DOW%)==(Mon) alarmTSR.exe 10:30 Time for Monday staff meeting
  3377.  
  3378. if (%DOW%)==(Fri) echo Running Friday backup.  Please wait...
  3379. if (%DOW%)==(Fri) CALL BACKUP C: 
  3380. if (%DOW%)==(Fri) CALL BACKUP D: 
  3381. set dow=
  3382.  
  3383.  
  3384.  
  3385. :63 Run a program at a specified time later in the day
  3386. :==================================================================
  3387. COMMENT
  3388.   This batch file involves a lot of disk activity because DOS re-reads the
  3389.   batch file from disk every time it does a GOTO LOOPTOP.  You can avoid
  3390.   all this disk activity by running the batch file from a RAM DISK.
  3391.  
  3392. REM GET CURRENT ABSOLUTE MINUTE AND PUT IN ENVIRONMENT VARIABLE RUNTIME
  3393. FDATE /Ff /At /Ominute#  |STRINGS RunTime= ASK >NUL
  3394.  
  3395. REM ADD 120 MINUTES (2 HOURS) TO ENVIRONMENT VARIABLE RUNTIME
  3396. FDATE /F#add /A%RunTime% /B120 |STRINGS RunTime= ASK >NUL
  3397.  
  3398. REM LOOP UNTIL NOWTIME HAS REACHED RUNTIME
  3399. :LoopTop
  3400.   FDATE /Ff /At  /Ominute#   |STRINGS NowTime=  ASK >NUL
  3401.   FDATE /F#comp  /A%NowTime% /B%RunTime% |STRINGS TimeComp= ASK >NUL
  3402.   if (%TimeComp%)==(LT) goto loopTop
  3403. :LoopEnd
  3404.  
  3405. echo STARTING EXECUTION OF APPLICATION: [program name]
  3406.  
  3407.  
  3408.  
  3409. :66 Change a filename to contain today's date in first 3 bytes
  3410. :==================================================================
  3411. FDATE /Ff /Oxxx /vXXX
  3412. ren  BACKUP.LOG  %XXX%-BACK.LOG
  3413. SET  XXX=
  3414.  
  3415.  
  3416.  
  3417. :67 Change a file's name to a name that contains today's date
  3418. :==================================================================
  3419. :: today's date (/At) in CCYYMMDD format into environment variable DATE1
  3420. FDATE /Ff /At /Occyymmdd /Vdate1
  3421. :: rename BACKUP.LOG to ccyymmdd.LOG (ex. 19950508.LOG on May 8, 1995)
  3422. REN BACKUP.LOG  %date1%.LOG
  3423. SET DATE1=
  3424.  
  3425.  
  3426. :68 Change a file's name to a name containing an absolute minute 
  3427. :===============================================================
  3428. COMMENT
  3429.   This is a way to keep a complete series of files, such as log files,
  3430.   that are all created with the same name on the same day.  The only
  3431.   requirement is that they be created at least one minute apart.  You
  3432.   won't need to be able to decipher the absolute minute to figure out when
  3433.   the file was created; you can simply do a DIR on the file and look at
  3434.   its date/time stamp.  
  3435.  
  3436. FDATE /FF /At /Ominute# /VJulMin
  3437. REN online.log %JulMin%.log
  3438. SET JulMin=
  3439.  
  3440.  
  3441.  
  3442. :71 Extract the rightmost n characters of a string 
  3443. :===============================================================
  3444. rem extract the rightmost 6 characters of a string
  3445.  FDATE /Fsubstr /a-6     /Q"1994 Jun 03"   ===> "Jun 03"
  3446.  
  3447.  
  3448.  
  3449. :72 Left-pad a number with zeroes, or a string with spaces
  3450. :===============================================================
  3451. :: pad a number (stored in environment variable) STRING
  3452. :: to the left with zeroes, to make sure it is 4 bytes long
  3453. set STRING=1
  3454. Fdate /FE  /Q%STRING% /Jr04  /Vstring
  3455. echo STRING is [%string%]
  3456.  
  3457. :: pad a string (stored in environment variable) STRING
  3458. :: to the left with spaces, to make sure it is 4 bytes long
  3459. set STRING=aa
  3460. Fdate /Fe  /Q%STRING% /J"r 4"  /Vstring
  3461. echo STRING is [%string%]
  3462.  
  3463. HOW FDATE THINKS ABOUT DATES
  3464. ============================
  3465.  
  3466. FDATE'S BUSINESS VIEW OF THE CALENDAR
  3467. =====================================
  3468.  
  3469.   FDATE is intended for business applications, not historical ones.  
  3470.  
  3471.   FDATE does not take into account historical changes in the calendar such
  3472.   as the ten days that were dropped from the British calendar when Britain
  3473.   moved from the Julian to the Gregorian calendar in the 18th century, or
  3474.   the 11 days that were dropped from the Russian calendar when Russia made
  3475.   the same move in the early 20th century.
  3476.  
  3477.   As far as FDATE is concerned, the calendar has followed the same
  3478.   pattern, unchanged, since January 1, 0001.
  3479.  
  3480.  
  3481. FDATE'S BASE DATE
  3482. =================
  3483.   Internally, Fdate's date manipulations are based on translating a
  3484.   calendar date into an "absolute" or "TRUE Julian" date:  a date
  3485.   expressed as the number of days from some day in the distant past.
  3486.  
  3487.   FDATE's base date is January 1, 0001 (i.e. day 1 of month 1 of year 1)
  3488.   FDATE's absolute date for January 1, 0001 is      1.
  3489.   FDATE's absolute date for January 1, 1992 is 727198.
  3490.  
  3491.  
  3492. FDATE'S LEAP YEAR ALGORITHM
  3493. ===========================
  3494.     Every year evenly divisible by 4 IS a leap year
  3495.       EXCEPT THAT
  3496.         Every year evenly divisible by 100 IS NOT a leap year
  3497.           EXCEPT THAT
  3498.             Every year evenly divisible by 400 IS a leap year
  3499.     .
  3500.     Using this algorithm
  3501.          1983  is not a leap year
  3502.          1984  is     a leap year
  3503.          1900  is not a leap year
  3504.          2000  is     a leap year
  3505.  
  3506.     See "A Machine Algorithm for Processing Calendar Dates", by
  3507.          Henry F. Fliegel (Georgetown University Observatory) and
  3508.          Thomas C. Van Flandern (U.S. Naval Observatory)
  3509.          COMMUNICATIONS OF THE ACM, Volume 11, Number 10, October 1968
  3510.  
  3511. There is supposedly a new adjustment to the leapyear algorithm,
  3512. which specifies the additional exception:
  3513.  
  3514.               EXCEPT THAT
  3515.                 Every year evenly divisible by 4000 IS a leap year
  3516.  
  3517. See "Bit By Bit" column, COMPUTER LANGUAGE, November 1989, p. 148.
  3518. This adjustment is not part of FDATE's leapyear algorithm.
  3519. Unless your application is working with dates 2,000 years in the
  3520. future, the lack of this exception will be irrelevant for you.
  3521.  
  3522. FDATE'S CENTURY-ASSUMPTION ALGORITHM
  3523. ====================================
  3524. If an input date is supplied in a format in which the year is
  3525. specified without a century -- that is, as YY rather than CCYY --
  3526. then Fdate does not automatically use the current century.
  3527. Instead,
  3528.  
  3529.    *  if YY is greater than 20,       then FDATE assumes CC = 19
  3530.    *  if YY is less than or equal 20, then FDATE assumes CC = 20
  3531.  
  3532. Examples:
  3533.          21    becomes  1921
  3534.          ...
  3535.          99    becomes  1999
  3536.          00    becomes  2000
  3537.          01    becomes  2001
  3538.          ...
  3539.          20    becomes  2020
  3540. but then (again)
  3541.          21    becomes  1921
  3542.  
  3543. To put it simply, FDATE makes what would be a reasonable assumption about
  3544. the century for someone operating in the 1990's: it looks back to 1921 and
  3545. forward to 2020.  If I, FDATE, and DOS are still alive in the year 2005
  3546. (which, given the introduction of Windows 95, seems unlikely) I'll probably
  3547. update FDATE's century-assumption algorithm to shift it forward several
  3548. decades.
  3549.  
  3550.  
  3551. FDATE'S IMPLEMENTATION LIMITS
  3552. ====================================
  3553. Internally, numbers in Fdate are stored in Turbo Pascal's LONGINT datatype,
  3554. which means that Fdate can accept numbers up to 9 digits long.
  3555.  
  3556. DISTRIBUTION ISSUES
  3557. ===================
  3558.  
  3559. USE, REGISTRATION, AND DISTRIBUTION OF FDATE
  3560. ============================================
  3561.  
  3562. FDATE is freeware, or what is known as "zero-cost shareware".  FDATE is not
  3563. what is technically called "public domain" software because the author
  3564. retains the copyright.  FDATE can, however, be copied, used, and
  3565. distributed freely as long as FDATE.EXE and its associated doc file
  3566. (FDATE.TXT) and demonstration batch files and doc files (HOLIDAYS.BAT,
  3567. HOLIFEDS.BAT, HOLIFEDS.TXT) are not altered and are distributed together.  
  3568.  
  3569. There is no requirement to register FDATE in any way.
  3570.  
  3571. FDATE can be included in shareware packages as long as both FDATE and
  3572. its related files are included in the shareware package.
  3573.  
  3574. If you have received FDATE as part of some larger shareware package,
  3575. please be aware that you may freely use, copy, and distribute FDATE
  3576. without paying a fee for, or registering, the larger package.
  3577.  
  3578. The author explicitly disavows any claim whatsoever about the
  3579. correctness or functionality of FDATE, its documentation, and its
  3580. demonstration batch files, and disclaims liability for anything and
  3581. everything bad that might happen in connection with, before, during, or
  3582. after using it.  I have tried to make FDATE work right, but everybody
  3583. makes mistakes, so you use FDATE at your own risk.
  3584.  
  3585. I don't know if people will find FDATE useful, and I'd like to find
  3586. out.  If you find FDATE useful and use it on a regular basis, I'd
  3587. appreciate it if you would drop me a short note via US mail or
  3588. CompuServe, telling me about how you are using FDATE.
  3589.  
  3590. If you need other input/output formats, please contact the author.
  3591.  
  3592.  
  3593. TECHNICAL SUPPORT FOR FDATE
  3594. ===============================================
  3595.  
  3596. Send me a message via CompuServe mail; I'll respond.  When sending your
  3597. message, please let me know what version of Fdate you're using.
  3598.  
  3599.  
  3600. WHERE TO FIND THE MOST CURRENT VERSION OF FDATE
  3601. ===============================================
  3602.  
  3603. You will always be able to find the most recent version of FDATE on
  3604. CompuServe.  The filename will be FDATE.ZIP, and it will be available in
  3605. the CIS:IBMSYS forum (library 1, the "DOS Utilities" library).
  3606.  
  3607. If you have problems finding it, try using cross-library searching, looking
  3608. for the filename FDATE.ZIP or the keyword FDATE.
  3609.  
  3610.  
  3611. UPLOADING FDATE TO ELECTRONIC BULLETIN BOARDS
  3612. ===============================================
  3613.  
  3614. Feel free to post copies of FDATE.ZIP on any BBS that you wish, but please
  3615. do not upload it to any CompuServe library.  As long as I am the only one
  3616. putting copies of FDATE onto CompuServe, we can keep confusion over
  3617. versions to a minimum.
  3618.  
  3619. I distribute all versions of FDATE in a files called FDATE.ZIP, rather than
  3620. embedding information about the version in the file name.  I think doing
  3621. this helps newer versions of FDATE to force older versions out of
  3622. circulation.  To give a BBS user information about the version, I always
  3623. identify the version of FDATE in the 1-line file description that most BBSs
  3624. support.  
  3625.  
  3626.  
  3627. CONTENTS OF THE FDATE.ZIP DISTRIBUTION FILE
  3628. ===========================================
  3629.  
  3630. The current distribution package (FDATE.ZIP) contains the following:
  3631.  
  3632.        FDATE.EXE         [the FDATE program]
  3633.        FDATE.TXT         [this file, documentation for FDATE]
  3634.        FDATEBEG.TXT      [FDATE beginners documentation]
  3635.  
  3636.   [demonstration batch files]
  3637.        HOLIDAYS.BAT
  3638.        HOLIFEDS.BAT and HOLIFEDS.TXT
  3639.  
  3640.   [documentation files for use in BBS distribution]
  3641.        FILE_ID.DIZ
  3642.    DESC.SDI
  3643.  
  3644.  
  3645. RECENT FDATE REVISION HISTORY
  3646. =============================
  3647.  
  3648. Letters appended to version numbers indicate modifications to
  3649. the doc files, without any modification to the FDATE.EXE software.
  3650. Asterisks (*) indicate most important changes in the new version.
  3651.  
  3652. 7.0a   Nov 14, 1992
  3653.        Added #mod function
  3654.        Major reformatting of documentation to make it more user-friendly
  3655.    
  3656. 7.1a   Apr 15, 1993
  3657.        Added German language support.  Thanks for the request, and the
  3658.        necessary information, from Patrick Schmucki, via the Active-Net
  3659.        BBS in Rapperswil, Switzerland.
  3660.  
  3661. 8.0    July, 1993
  3662.        Added "V" (validate) and "m" (month addition/subtraction) functions
  3663.        Added math functions: #mult #div #idiv
  3664.        Added /T (time) parameter
  3665.  
  3666.        Added FORATIME.BAT example, which Walter Ledge (assistant sysop of
  3667.        CompuServe's CRFORUM) and I developed.  A big thanks to Walt for
  3668.        his feedback and help.
  3669.  
  3670. 8.1    July 27, 1993  BUG FIX
  3671.        An error-trapping routine that was added to version 7.9 contained a
  3672.        bug that caused Fdate's numeric math functions (#add, #dif, #mult,
  3673.        #div, #idiv, #mod, #comp, etc.) to return incorrect results. 
  3674.        
  3675. 8.2    August, 1993
  3676.        Removed FILEDATE.BAT from the distribution .ZIP file.
  3677.  
  3678.        Corrected the Spanish and French "full" and "d1" output formats. 
  3679.        Thanks for the information on Spanish and French date formats to
  3680.        Gene J. Raymond, of GJR Software Products.
  3681.  
  3682. 8.3a   Feb 24, 1994
  3683.  
  3684. *      Added the following string-handling functions:
  3685.        get    (get user input)
  3686.        getu   (get uppercase user input)
  3687.       upper  (uppercase a string)
  3688.        len    (length of a string)
  3689.        substr (substring)
  3690.  
  3691. *      Added /F#2xx (convert number to extended hex format) function. 
  3692.        Deleted SETXX.BAT, which has been made obsolete with the addition
  3693.        of this new function.  Modified second example of storing a 4-digit
  3694.        date to use #2xx instead of SETXX.BAT.
  3695.  
  3696. *      Added output formats "ddmmccyy" and "ddmmyy" at the request of
  3697.        several users.
  3698.  
  3699. *      Added output format "xxx" after several requests for advice on how
  3700.        to represent a large range of dates in a minimum number of bytes
  3701.        (usually for constructing filenames from today's date).
  3702.  
  3703. *      At the request of several users, enhanced the "compare" functions
  3704.        (comp, tcomp, #comp) so they set distinctive errorlevels for their
  3705.        different results.  See the table of contents ("COMPARE-FUNCTION
  3706.        ERRORLEVELS") and EXAMPLES.
  3707.  
  3708.        To discussion of /Fv parameter, added note about almost always
  3709.        redirecting output to NUL when using /Fv.
  3710.  
  3711.        Revised FORATIME.BAT example batch file to make error-correction a
  3712.        bit more robust and to add better documentation on how to use it.
  3713.  
  3714.        Added example batch files to use new functions, especially
  3715.        FORATIM2.BAT which uses new "get" function
  3716.  
  3717.        Removed FDATEX.BAT demonstration batch file from distribution
  3718.        package, to reduce its size.  The examples in this DOC file should
  3719.        make the examples in FDATEX.BAT unnecessary
  3720.  
  3721.  
  3722. 8.4a   March 20, 1994
  3723. *      Added GETK (get keypress) function
  3724.  
  3725. *      Added ability to use /V when running in a Windows DOS box, thanks
  3726.        to a Turbo Pascal routine from the Turbo Professional library
  3727.        provided by Kim Kokkonen of TurboPower Software.
  3728.  
  3729.        Fixed a bug in which the prompt string (/Q) for the GET and GETU
  3730.        functions was being written to redirectable output (StdOut).  The
  3731.        prompt string is now written directly to the screen, and will not
  3732.        appear in FDATE's output when the output is redirected to a file.
  3733.  
  3734.        Removed ALARM.BAT, ALARM.DOC, TIC.BAT and TIC.DOC from distribution
  3735.        package.  They were too esoteric to be generally helpful.
  3736.  
  3737.        Added FILE_ID.DIZ and DESC.SDI to distribution package.
  3738.  
  3739.        Corrected algorithm for Mardi Gras in HOLIDAYS.BAT.  Modified
  3740.        HOLIDAYS.BAT and HOLIFEDS.BAT to make them more interactive, using
  3741.        FDATE's new abilities to get user input.
  3742.  
  3743. *      Started ZIPing FDATE.ZIP with PKZIP 2.04g rather than version 1.1
  3744.  
  3745. 8.4b   April 2, 1994
  3746.        Revised example :08, to use /fgetK rather than /fgetU
  3747.        Fixed formatting of #dif function
  3748.        Reformatted examples to reduce number of printed pages
  3749.        Duplicate example :07 was renumbered 
  3750.        FORATIME.BAT (original version) removed as no longer interesting
  3751.        Modified JDATE.BAT to use new /Fget function
  3752.  
  3753.   8.4cSeptember 6, 1994
  3754.        Revised HOLIDAYS.BAT so it would not go into an infinite loop if
  3755.        run on a system where FDATE cannot manipulate the environment, and
  3756.        to pad the year to the left with zeroes, so years before 1000 will
  3757.        be accepted.
  3758.  
  3759.   Added example showing how to left-pad a number with zeroes.
  3760.  
  3761.        Rewrote example showing how to time execution of a program.
  3762.  
  3763.   Updated my home mailing address after moving.
  3764.  
  3765.        Corrected information on how to make sure you have enough
  3766.        environment space in a Windows DOS box.  Thanks for the feedback
  3767.        and on this issue from Ronny Richardson.
  3768.  
  3769.        Added WHATDAY.BAT (example :14).  Thanks for the request from Cal
  3770.        Pryluck, Radio-Television-Film, Temple University, Philadelphia
  3771.  
  3772.   8.5aSeptember 28, 1994
  3773.        Added output date format "mmddyy" (PKZIP's "American" date format),
  3774.        and an example showing how to use Fdate to get a date for use with
  3775.        PKZIP for archiving files.  Thanks for the tip on PKZIP's input
  3776.        formats from Dick Jensen.
  3777.  
  3778.   8.6aOctober 27, 1994
  3779.        Corrected a bug in output format T1: HOUR value was being prefixed
  3780.        by a leading zero if MINUTE value was less than 10.
  3781.  
  3782. 8.7a   October 27, 1994
  3783.        Added output format TDOS, which mimics the format used in the DOS
  3784.        "time" command.  Added an example using it to the "roll your own"
  3785.        date format example (:19) as example (a).  Thanks for the request
  3786.        for this common time format from Roy Zider.
  3787.  
  3788.   8.8aNovember 06, 1994
  3789.        Changed error action in cases in which the prefix parm /P was
  3790.        specified.  In case of an error, the first line generated will
  3791.        always be "ERROR".  If prefix parm was specified, then a second
  3792.        line will be generated with the prefix followed by "ERROR".  Thus,
  3793.        if output is being routed to a batch file, and the prefix is
  3794.        something like "@set fdate=", then that will continue to work.
  3795.  
  3796.        Removed the example of using /Fe to put equal-signs and redirection
  3797.        symbols into the environment.  I doubt if anyone found this example
  3798.        useful.
  3799.  
  3800.        Added ability to break out of HELP using the ESC key
  3801.  
  3802.  *Added justify parm (/J)
  3803.   Re-wrote HOLIDAYS.BAT to illustrate uses for /J.
  3804.  
  3805. 8.9a   1995 Feb 15
  3806.  *Added "absolute month" output format (/Omonth#)
  3807.        Added example YMD_DIF.BAT, which uses new /Omonth# facility
  3808.   Added FDATEBEG.TXT to the distribution .ZIP file
  3809.  
  3810. 9.0a   1995 Feb 20
  3811.        prefixed "@" to the "echo ERROR ... " and "pause" that are
  3812.        generated when Fdate detects an error.  This should make error
  3813.        messages a bit easier to decipher.
  3814.  
  3815. 9.1a   1995 May 15
  3816.        Corrected bug that gave runtime error when function was #mult and
  3817.        /A parm was 0.
  3818.  
  3819.   9.1b1995 June 12
  3820.        Corrected example of Japanese date format in this DOC file.  Thanks
  3821.        to Christopher Clark for pointing out the typo.
  3822.  
  3823.   9.1c1995 Oct 22
  3824.        Added a usage example to the discussion of the "file" input format
  3825.        (/If).  Thanks to Bob Stephan for the suggestion.
  3826.  
  3827. 9.1d   1995 Dec 08
  3828.        Added comments to example :67 (putting date into filename) and
  3829.        changed output format to ccyymmdd.  Hopefully, these changes will
  3830.        make this popular example more useful and easier to understand.
  3831.  
  3832. 9.2a   1996 Jan 28
  3833. *      Added /X (exclude) parm to /Fw (weekday arithmetic function). 
  3834.        Added appropriate documentation, and examples :46 and :47.  Thanks
  3835.        to Richard Rogers for a real-life application that required this
  3836.        feature.
  3837.  
  3838. 9.2b   1996 Feb 1
  3839.        Rectified a minor documentation omission; I'd forgot to add /X to
  3840.        the overview list of FDATE parms. 
  3841.        Expanded FDATEBEG.TXT by adding the overview of things you can do
  3842.        with FDATE.
  3843.  
  3844. 9.3a   1996 Apr 19
  3845.        Added output format mmddccyy.
  3846.        Added information on using Fdate with Windows NT.
  3847.        Added specific information on Garrett Wolman's FDATE.
  3848.  
  3849. 9.4a   1996 Jun 10 
  3850.        Added input formats DAY# and MINUTE#.  This should enable a person
  3851.        to use Fdate to produce an absolute date or minute (using the DAY#
  3852.        or MINUTE# output format), manipulate it as he wishes (possibly in
  3853.        ways not supported by Fdate), and then convert the result back into
  3854.        a more readable format.  Specifically, this should allow a person
  3855.        to do "minute arithmetic" as well as "date arithmetic". Thanks to
  3856.        Kevin Jackson, of the New York State Executive Chamber, who
  3857.        reported the need to do time arithmetic.
  3858.  
  3859.        Added the MIN_MATH.BAT and TIME_SET.BAT examples.  
  3860.        Added news about TurboPower's withdrawal of support for
  3861.        environment-manipulating routines to documentation of /V parm under
  3862.        Windows NT.
  3863.  
  3864. 9.4b   1996 Jun 24 
  3865.        Corrected minor bug in TIME_SET.BAT example.
  3866.  
  3867. 9.5a   1997 March 17 
  3868.        Added #random function
  3869.        Added HHMMSSCC and HH:MM:SS:CC output formats 
  3870.  
  3871. 9.6a   1997 April 22
  3872.        Fixed design flaw, in which justification was being applied to the
  3873.        entire output string, including prefix string and suffix string. 
  3874.        Now, justification is applied BEFORE prefix and suffix strings are
  3875.        added to output. 
  3876.  
  3877.        This essentially broke the "ECHO" function /FE.  So a /Q parm was
  3878.        added to the echo function that permits it to still be used with
  3879.        justification (the /J parm).  Modified all of the /FE examples that
  3880.        us justification, to show them working with the /Q parm rather than
  3881.        with /P.  Modified HOLIDAYS.BAT, which was affected by this change.
  3882.  
  3883.        Renamed all .DOC files to .TXT
  3884.  
  3885.        Added contact info for Garrett Wollman and PSL.
  3886.